4

我正在尝试使用ExecutorServicewithBlockingQueue<Runnable>但退出脚本时遇到问题。它完成没有问题,但然后继续等待,我不知道是什么。

首先我有一堂课

public class GenericTask implements Runnable {
    public void run() {
        // do stuff
    }
}

那么这是代码

BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10000, true);
ExecutorService myExecutor = Executors.newFixedThreadPool(numThreads);

new Thread(new Runnable() {
    public void run() {
        for (; ; ) {
            try {
                myExecutor.execute(queue.take());
            } catch (InterruptedException ignored) {
            }
        }
    }
}).start();

while (...) {
    queue.put(new GenericTask());
}

int waitTime = 500;
myExecutor.shutdown();
try {
    while (!myExecutor.awaitTermination(waitTime, TimeUnit.MILLISECONDS)) {
        logger.info("Waiting...");
        Thread.sleep(waitTime);
    }
} catch (Exception e) {
    e.printStackTrace();
}

System.out.println("Finished!");

当它打印“完成!”时,它真的完成了,但是除非我添加一个,否则脚本会继续进行System.exit(0),但我认为这是不正确的。

4

1 回答 1

4

最后,您正确地关闭了线程池中的所有线程。但是还有另一个非守护线程阻止 JVM 终止。你能发现吗?这是你的匿名生产者线程,里面有无限循环:for (;;)

使用Thread.setDaemon(true)

Thread t = new Thread(new Runnable() {
  //...
});
t.setDaemon(true);
t.start();

现在,当所有线程在ExecutorService关闭后终止时,main线程也会终止并且 JVM 将停止,因为您唯一剩余的线程是一个守护进程。

于 2013-01-11T21:59:48.150 回答