在阻塞队列中等待时的中断
问题描述:
我有一个Runnable
,它从Executor
运行。
可运行模块被阻止在SychronousQueue.take
中等待。如何确保take
在我executor.shutdown
时会中断?在阻塞队列中等待时的中断
答
+1 to @Eugene。 ExecutorService.shutdown()
关闭线程池,但任何提交的作业都将继续运行直至完成。如果您使用shutdownNow()
,它实际上会中断这些线程。这并不意味着他们会立即停止,但这意味着如果他们被阻止在queue.take()
或他们的下一个电话queue.take()
它会抛出InterruptedException
,以便线程可以退出。
从的Javadoc引用:
尝试停止所有正在执行的任务,暂停等待任务的处理,并返回等待执行的任务列表。
除了竭尽全力尝试停止处理主动执行的任务之外,没有任何保证。例如,典型的实现将通过Thread.interrupt()取消,所以任何不能响应中断的任务都不会终止。
当你的线程都呼吁queue.take()
他们应该有类似下面的代码:
try {
work = queue.take();
...
} catch (InterruptedException e) {
// re-interrupt the thread which is always a good pattern
Thread.currentThread().interrupt();
// quit the processing thread
return;
}
答
你可以做这样的事情吗?
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIME)) {
executor.shutdownNow();
}
答
正如javadoc of take指定它会抛出一个InterruptedException
当线程在等待被中断。因此,您需要确保您的执行程序实施将在shutdown
上拥有的所有线程上调用Thread.interrupt()。
shutdownNow时?也许 – Eugene 2013-03-26 10:49:14
ShutdownNow只是不执行其余的任务。问题是当线程被阻塞在'take'时会发生什么 – Jim 2013-03-26 10:51:17
事情是SynchronousQueue可能是空的,因此take()会阻塞,直到put()会发生。你可以用LinkedBlockingQueue替换它吗? – Eugene 2013-03-26 10:53:46