这是否被认为是生产者,消费者场景中的一个bug?
,这是我的制作人班。。
package com ;
import java.util.concurrent.PriorityBlockingQueue;
public class Producer extends CommonClass implements Runnable {
private SyncronizedStack stack;
private int producerNum;
Producer(PriorityBlockingQueue<Character> queue) {
this.queue = queue;
}
public void run() {
char ch;
for (ch = 'a'; ch <= 'f'; ch++) {
queue.add(ch);
System.out.println("Producer" + producerNum + "produced :" + ch);
try {
Thread.sleep((int) (Math.random() * 300));
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
}这是我的消费类
package com ;
import java.util.concurrent.PriorityBlockingQueue;
public class Consumer extends CommonClass implements Runnable {
private int consumerNum;
Consumer(PriorityBlockingQueue<Character> queue) {
this.queue = queue;
}
public void run() {
char c;
for (int i = 0; i < 7; i++) {
try {
c = queue.take();
System.out.println("Consumer" + consumerNum + "consumed:" + c);
} catch (Exception e1) {
e1.printStackTrace();
}
try {
Thread.sleep((int) (Math.random() * 300));
} catch (InterruptedException e) {
System.out.println("Error");
}
}
}
},这是我的CommonClass
package com ;
import java.util.concurrent.PriorityBlockingQueue;
public class CommonClass {
PriorityBlockingQueue<Character> queue = null;
}这是我的客户程序
package com ;
import java.util.concurrent.PriorityBlockingQueue;
public class SyncTest {
public static void main(String[] args) {
CommonClass cs = new CommonClass();
PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>();
Producer p1 = new Producer(queue);
Thread t1 = new Thread(p1);
t1.start();
Consumer c1 = new Consumer(queue);
Thread ct1 = new Thread(c1);
ct1.start();
}
}当我运行时,输出作为
Producer0produced :a
Consumer0consumed:a
Producer0produced :b
Consumer0consumed:b
Producer0produced :c
Consumer0consumed:c
Producer0produced :d
Consumer0consumed:d
Producer0produced :e
Producer0produced :f
Consumer0consumed:e
Consumer0consumed:f这是在e和f字母的情况下。
这个输出有什么问题吗?正如我所看到的那样,Producer0produced语句两次同时出现,然后对字母e和f同时接Consumer0consumed语句。
我担心用这个代码我会错过由生产者??生成的任何信息
请给我建议?
谢谢你的建议。
发布于 2012-09-20 13:50:13
这个输出有什么问题吗?
不是的。您的生产者线程在使用者使用第一个项目之前,刚刚成功地生成了第二个项目。这是完全自然的,特别是当你随意睡觉的时候。
当然,您可能希望给队列设置一个上限,然后使用offer而不是add来检测队列已满的情况--但是您显示的输出很好。
发布于 2012-09-20 13:50:26
正如我所看到的那样,Producer0produced语句两次同时出现,然后对字母e和f同时接Consumer0consumed语句。
不,这是意料之中的。您正在演示多个线程的典型异步行为。在消费者睡觉的时候,制片人能制作出两封信。
这种情况将会发生,尤其是考虑到生产者和消费者都在随意睡觉:
Thread.sleep((int) (Math.random() * 300));但是即使没有睡眠,这种不对称的行为也是线程程序所期望的。
发布于 2012-09-20 14:25:22
这是个bug吗?
答案-,NO,,它之所以发生,是因为你增加了不必要的睡眠。
Thread.sleep((int) (Math.random() * 300));我已经简化了你的生产者消费者的版本如下。
public class Example {
public static class Producer implements Runnable {
private PriorityBlockingQueue<Character> queue;
Producer(PriorityBlockingQueue<Character> queue) {
this.queue = queue;
}
public void run() {
char ch;
for (ch = 'a'; ch <= 'f'; ch++) {
queue.put(ch);
}
}
}
public static class Consumer implements Runnable {
private PriorityBlockingQueue<Character> queue;
Consumer(PriorityBlockingQueue<Character> queue) {
this.queue = queue;
}
public void run() {
for (int i = 0; i < 7; i++) {
try {
System.out.println("Consumer take :" + queue.take());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();// Propagate interrupt
}
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>(7);
executorService.execute(new Producer(queue));
executorService.execute(new Consumer(queue));
executorService.shutdown();
}
}https://stackoverflow.com/questions/12514042
复制相似问题