2013-03-26 30 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()