我有非常简单的代码,它使用“Poison Pill”模拟生产者/消费者停止技术。
我有Producer类:
public class Producer extends Thread {
private final BlockingQueue<String> queue;
public Producer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
//unblocking this line will cause the code to stop after intrrupt
//System.out.println("1");
queue.put("hello world");
}
} catch (InterruptedException e) {
try {
queue.put(Main.POISON_PILL);
} catch (InterruptedException e1) {
}
}
}
}
消费者类:
public class Consumer extends Thread {
private final BlockingQueue<String> queue;
public Consumer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
String s = queue.take();
if (s.equals(Main.POISON_PILL))
break;
else
System.out.println(s);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
现在主要功能:
public static String POISON_PILL = "POISON_PILL";
public static void main(String[] args) {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
producer.start();
consumer.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
} finally {
producer.interrupt();
}
}
即使在producer.interrupt()
调用之后,还有未知原因,
“你好世界”永远在控制台中打印。
我无法理解的第二件事是,为什么取消注释System.out.println("1");
会导致程序在生产者线程中断后退出。
请帮助我理解原因。
答案 0 :(得分:4)
我的猜测是你的制作人只是比你的消费者跑得快得多,你出现永远不会用完物品。创建一个没有显式容量的LinkedBlockingQueue
会创建一个容量为Integer.MAX_VALUE的容量,这足以让消费者保持打印很长时间。
这也可能是你添加System.out.println
行时开始工作的原因;通过要求控制台I / O,它可以使生产者减慢到消费者能够跟上的程度。
尝试创建一个容量较小的LinkedBlockingQueue
,例如100左右。