BlockingQueue程序不会退出

时间:2016-07-29 03:23:23

标签: java multithreading

我指的是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的理解是,它是生产者 - 消费者模式的替代解决方案。

所以我们需要两个线程来处理。因此,我有疑问/问题。

以下是我的问题。

  1. 他们是否使用主线程作为另一个线程?

  2. 当我运行应用程序时,程序不会退出。我不明白主程序没有退出的原因?

2 个答案:

答案 0 :(得分:1)

在您所引用的示例代码中,您有一个生产者Main主题)和两个使用者Worker主题)。

在生产者 - 消费者问题中,没有必要只有一个生产者而只有一个消费者 - 你可以拥有多个生产者和多个消费者。他们的相对数量通常决定谁在做更复杂和耗时的任务。

答案1: 主线程是生产者线程,因为它用于将项目放到BlockingQueuequeue.put(i)

答案2:你的主要线程在将十个元素放入队列后退出,但是你的工作线程一直在等待元素(即使在消耗了十个元素之后),因为q.take()是一种阻塞方法,即它等待更多元素放入队列(当queue为空时)

解决方案:您需要将两个EOF元素/ ObjectsEND 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来调试并查看每个线程上实际发生的事情