我指的是BlockingQue的概念,我发现了一个例子here。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /* j a v a 2s . co m*/
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue < Integer > queue = new ArrayBlockingQueue < Integer > (capacity);
int numWorkers = 2;
Worker[] workers = new Worker[numWorkers];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Worker(queue);
workers[i].start();
}
for (int i = 0; i < 10; i++) {
queue.put(i);
}
}
}
class Worker extends Thread {
BlockingQueue < Integer > q;
Worker(BlockingQueue < Integer > q) {
this.q = q;
}
public void run() {
try {
while (true) {
Integer x = q.take();
if (x == null) {
break;
}
System.out.println(x);
}
} catch (InterruptedException e) {}
}
}
在该示例中,他们只使用了一个作为工作线程的线程。
我对BlockingQue
的理解是,它是生产者 - 消费者模式的替代解决方案。
所以我们需要两个线程来处理。因此,我有疑问/问题。
以下是我的问题。
他们是否使用主线程作为另一个线程?
当我运行应用程序时,程序不会退出。我不明白主程序没有退出的原因?
答案 0 :(得分:1)
在您所引用的示例代码中,您有一个生产者(Main
主题)和两个使用者(Worker
主题)。
在生产者 - 消费者问题中,没有必要只有一个生产者而只有一个消费者 - 你可以拥有多个生产者和多个消费者。他们的相对数量通常决定谁在做更复杂和耗时的任务。
答案1: 主线程是生产者线程,因为它用于将项目放到BlockingQueue
,queue.put(i)
答案2:你的主要线程在将十个元素放入队列后退出,但是你的工作线程一直在等待元素(即使在消耗了十个元素之后),因为q.take()
是一种阻塞方法,即它等待更多元素放入队列(当queue
为空时)
解决方案:您需要将两个EOF
元素/ Objects
(END OF FILE
)排入队列并像您一样进行检查,{{1} }。尝试将两个额外的空值放入队列中,这样当您的工作者/消费者线程找到它时,它们将终止。目前,您的条件if (x == null)
永远不会得到满足。
答案 1 :(得分:0)
答案1.没有他们没有使用主线程做其他事情。主线完全退出。
答案2.在所有非守护程序线程结束之前,JVM不会退出。 (来源:http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html)
如果您希望JVM在主线程完成后退出,请通过在for循环中添加workers[i].setDaemon(true);
使您的Worker线程成为守护程序线程。
你的非守护程序线程不存在的原因是你在Worker的run方法循环中有Integer x = q.take();
。因此,那些工作线程永远等待新的整数被放入队列。
建议:您可以使用Eclipse Java IDE来调试并查看每个线程上实际发生的事情