java实现生产者消费者模式
来源:互联网 发布:淘宝扫码付款被骗 编辑:程序博客网 时间:2024/06/01 19:56
生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次投放产品。
使用synchronized关键字实现线程同步
在使用wait()和notifyAll()方法时,应注意将wait()方法放入循环中,否则会产生虚假唤醒问题。
/** * Created by 吴海飞 on 2017-1-23. */public class TestProductAndConsumer { public static void main(String[] args){ Clerk clerk = new Clerk(); Productor pro = new Productor(clerk); Consumer consumer = new Consumer(clerk); new Thread(pro,"生产者A").start(); new Thread(consumer,"消费者B").start(); }}/** * 店员,可以进货与销售货物 */class Clerk{ private int product = 0; /** * 进货的方法 */ public synchronized void get(){ while (product>=1){//为了避免虚假唤醒问题,应该总是使用在循环中 System.out.println("产品已满!"); try { this.wait();//等待 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":" + ++product); this.notifyAll();//唤醒线程 } /** * 销售的方法 */ public synchronized void sale(){ while (product<=0){//为避免虚假唤醒,应该总是始终使用在循环中 System.out.println("缺货……"); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":"+ --product); this.notifyAll(); }}/** * 生产者 */class Productor implements Runnable{ private Clerk clerk; public Productor(Clerk clerk){ this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 10; i++){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } clerk.get(); } }}/** * 消费者 */class Consumer implements Runnable{ private Clerk clerk; public Consumer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 10; i++){ clerk.sale(); } }}
使用同步锁实现线程同步问题
使用同步锁时应注意lock()与unlock()方法的同步使用。
import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * 使用ReentrantLock实现生产者消费者问题 * Created by 吴海飞 on 2017-1-23. */public class TestReentrantLock { public static void main(String[] args){ Clerk clerk = new Clerk(); Productor pro = new Productor(clerk); Consumer consumer = new Consumer(clerk); new Thread(pro,"生产者A").start(); new Thread(consumer,"消费者B").start(); new Thread(pro,"生产者C").start(); new Thread(consumer,"消费者D").start(); }}class Clerk{ private Lock lock = new ReentrantLock();//获取同步锁 private Condition condition = lock.newCondition(); private int product = 0;/** * 进货的方法 */ public void get(){ lock.lock();//打开锁 try{ while (product>=1){//为了避免虚假唤醒问题,应该总是使用在循环中 System.out.println("产品已满!"); try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":" + ++product); condition.signalAll(); }finally { lock.unlock();//关闭锁 } }/** * 销售的方法 */ public void sale(){ lock.lock();//加锁 try { while (product<=0){//为避免虚假唤醒,应该总是始终使用在循环中 System.out.println("缺货……"); try { condition.await();//等待 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + ":"+ --product); condition.signalAll();//唤醒等待 }finally { lock.unlock();//释放锁 } }}/** * 生产者 */class Productor implements Runnable{ private Clerk clerk; public Productor(Clerk clerk){ this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 10; i++){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } clerk.get(); } }}/** * 消费者 */class Consumer implements Runnable{ private Clerk clerk; public Consumer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 10; i++){ clerk.sale(); } }}
0 0
- Java生产者消费者模式实现
- 生产者消费者模式Java实现
- 生产者消费者模式Java实现
- Java实现生产者/消费者模式
- java生产者消费者模式实现
- java实现生产者消费者模式
- java多线程实现生产者消费者模式
- Java 队列 实现生产者-消费者模式
- java使用LinkedBlockingQueue实现 生产者 消费者模式
- Java多线程实现消费者/生产者模式
- 设计模式-生产者与消费者Java实现
- Java多线程实现生产者消费者模式
- java 多线程实现生产者消费者模式
- Java使用BlockingQueue实现生产者消费者模式
- JAVA 生产者消费者模式的实现
- 生产者消费者模式的一种java实现
- java wait()/notify() 实现生产者消费者模式
- 简单的生产者消费者模式java实现
- EasyUI--tree的实现
- LeetCode 94. Binary Tree Inorder Traversal java solution
- JAVA软件开发之8例
- HDU 2571 命运 (动态规划)
- JQuery实现可以编辑的表格
- java实现生产者消费者模式
- 策略设计模式
- last_insert_id()函数使用的注意事项 mysql
- mysql迁移数据文件
- TYPESDK手游聚合SDK客户端设计思路与架构之二:安卓平台统一化接口结构及思路
- 3D游戏开发之在UE4中创建非玩家角色(NPC)
- SSH架构操作多数据库
- 致CSDN的感谢信
- TYPESDK手游聚合SDK客户端设计思路与架构之三:iOS平台统一化接口结构及思路