锁定老帖子 主题:Java并发实现生产者消费者模式
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (4)
|
|
---|---|
作者 | 正文 |
发表时间:2011-07-24
这个例子有点局限,消费者每次只能等生产者生产了n个Q后消费完这n个。
package com.test; class Q { int n; boolean valueSet = false; //Q的value是不是已经设置过了 synchronized int get() { if(!valueSet) try { wait(); //wait until Producer produce a product and notify -----A } catch(InterruptedException e) { System.out.println("InterruptedException caught"); } System.out.println("Got: " + n); valueSet = false; notify(); return n; } synchronized void put(int n) { if(valueSet) try { wait(); } catch(InterruptedException e) { System.out.println("InterruptedException caught"); } this.n = n; valueSet = true; System.out.println("Put: " + n); notify(); } } class Producer implements Runnable { Q q; Producer(Q q) { this.q = q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while(true) { q.put(i++); } } } class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while(true) { q.get(); } } } class PCFixed { public static void main(String args[]) { Q q = new Q(); new Consumer(q); new Producer(q); System.out.println("Press Control-C to stop."); } }
可是这里我有一个疑问,如果Consumer的线程先运行,调用get方法,在A处wait。接着Producer的线程运行,调用put方法,但是因为put是synchronized方法,不是应该等待get方法退出才能执行,这样不是应该死锁了么。但我执行过很多次,并不会死锁,这是为什么呢?还有,怎么在问答频道发帖呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-07-24
1、wait的时候会释放该对象的同步锁,这时其他线程是可以获得该对象的同步锁的。wait退出后会重新获得同步锁(在jvm里完成、并且包括异常的情况)。所以你的代码逻辑基本上是没有问题的,也不会有死锁。
2、最好把if(condition) wait() 改成 while(condition) wait() 3、你这个demo更像是Exchanger。典型的生产者/消费者模式是用队列缓存任务的,这样在一定程度上生产者和消费者是基于流水线的方式持续运行的,不必每次生产或消费都要等待对方。 |
|
返回顶楼 | |
发表时间:2011-07-25
taolei0628 写道 1、wait的时候会释放该对象的同步锁,这时其他线程是可以获得该对象的同步锁的。wait退出后会重新获得同步锁(在jvm里完成、并且包括异常的情况)。所以你的代码逻辑基本上是没有问题的,也不会有死锁。
2、最好把if(condition) wait() 改成 while(condition) wait() 3、你这个demo更像是Exchanger。典型的生产者/消费者模式是用队列缓存任务的,这样在一定程度上生产者和消费者是基于流水线的方式持续运行的,不必每次生产或消费都要等待对方。 谢谢,您说的是对的 |
|
返回顶楼 | |
发表时间:2011-07-26
请在 循环中 调用。Object.wait() 。具体请参照 Java API Doc。
if(!valueSet) 改成 while(!valueSet) if(valueSet) 改成 while(valueSet) |
|
返回顶楼 | |
发表时间:2011-07-26
不换成while肯定是有问题的。
|
|
返回顶楼 | |
发表时间:2011-07-26
小牛犊 写道 不换成while肯定是有问题的。
能解释下为什么不 |
|
返回顶楼 | |
发表时间:2011-07-26
新手来学习学习
|
|
返回顶楼 | |
发表时间:2011-07-26
chriszeng87 写道 小牛犊 写道 不换成while肯定是有问题的。
能解释下为什么不 chriszeng87 写道 消费者每次只能等生产者生产了n个Q后消费完这n个 |
|
返回顶楼 | |
发表时间:2011-07-26
用BlockingQueue实现比较简单,呵呵
|
|
返回顶楼 | |
发表时间:2011-07-27
应该是指“监视条件”吧,对象等待一般是条件不符合,对象被通知不一定符合执行的条件。当然就二个线程的时候跑起来挺欢的。多个线程使用notifyAll时可能就出问题了。而多个线程这种场景是最常见的。所以一般是while(条件不符合){wait();}
chriszeng87 写道 小牛犊 写道 不换成while肯定是有问题的。
能解释下为什么不 |
|
返回顶楼 | |