我使用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是否是最佳做法?