2017-04-07 18 views
0

我使用ExecutorCompletionService在完成其執行後立即獲取作業的結果。僞像這個 -
從ExecutorCompletionService獲取輸出的正確方法

Instantiate FixedThreadPool executor, exec 
Instantiate ExecutorCompletionService, completionService 
for(taskList) { 
    completionService.submit(someTask) 
} 
exec.shutDown(); 
whie(!exec.isShutdown()) { //Line 1 
    Task t = completionService.take(); //Line 2 
} 

正如我們所知,shutdown()等待所有提交的任務完成,所以只要有正在進行的任務,而在1號線條件返回true,代碼都在循環中從隊列中取出完成的任務並在必要時等待。
現在,我發現上面的代碼中存在一個問題,即在沒有更多任務正在進行的情況下,控制在line2上被阻止,所有任務都已完成。
我認爲這是因爲當最後一個任務完成並添加到完成隊列時,ThreadPoolExecutor恢復關閉過程,因爲沒有更多未完成的提交任務。但是它仍然關閉時,下一次迭代發生,並且isShutdown()返回false,因此它進入循環內部並被take()調用阻止,即使沒有更多任務。所以也許是最後take通話和游泳池正常關閉之間的時間。我正在朝着正確的方向思考?
所以我在想如果這是正確的方式來使用並從completionservice獲得結果? 要解決這個問題,我可以用for(taskList)替換line1上的while以避免isShutdown調用。 還有一件事是關閉執行程序,然後從completionservice獲取結果或首先收集結果並最終關閉execturo是否是最佳做法?

回答

0

嘗試使用isTerminated()代替isShutoown()。但最好的選擇是使用awaitTermination()方法而不是創建這個循環。