2013-03-26 29 views
0

我有一个Runnable,它从Executor运行。
可运行模块被阻止在SychronousQueue.take中等待。如何确保take在我executor.shutdown时会中断?在阻塞队列中等待时的中断

+1

shutdownNow时?也许 – Eugene 2013-03-26 10:49:14

+0

ShutdownNow只是不执行其余的任务。问题是当线程被阻塞在'take'时会发生什么 – Jim 2013-03-26 10:51:17

+0

事情是SynchronousQueue可能是空的,因此take()会阻塞,直到put()会发生。你可以用LinkedBlockingQueue替换它吗? – Eugene 2013-03-26 10:53:46

回答

2

+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; 
    } 
+0

但是,如果线程已经**在'take'中被阻塞,会发生什么? – Jim 2013-03-26 12:15:11

+0

它会立即抛出@Jim。我会将其添加到我的答案中。 – Gray 2013-03-26 12:16:21

2

你可以做这样的事情吗?

executor.shutdown(); 
    if (!executor.awaitTermination(SHUTDOWN_TIME)) { 
     executor.shutdownNow(); 
    } 
1

正如javadoc of take指定它会抛出一个InterruptedException当线程在等待被中断。因此,您需要确保您的执行程序实施将在shutdown上拥有的所有线程上调用Thread.interrupt()