从ExecutorCompletionService

时间:2017-04-07 17:49:23

标签: java executorservice

我使用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()等待所有提交任务的完成,因此只要有一个正在进行的任务,而Line1上的条件返回true并且代码进入循环以从中完成任务队列并在必要时等待 现在,我已经观察到上述代码存在问题,即使没有正在进行的任务,所有任务都已完成,控制在第2行上被阻止。 我认为这是因为当最后一个任务完成并添加到完成队列时,ThreadPoolExecutor将恢复关闭过程,因为没有更多待处理的已提交任务。但是当它仍在关闭时,下一次迭代发生并且isShutdown()返回false,因此它进入循环并被take()调用阻止,即使没有更多任务。所以也许是上次take通话和游泳池正常关闭之间的时间。我在想正确的方向吗?
所以我在想这是否是正确的使用方法并从完成服务中获得结果? 要解决此问题,我可以使用while替换第1行上的for(taskList),以避免isShutdown调用。 还有另一件事,关闭执行程序然后从完成服务获得结果或首先收集结果并最终关闭execturo是最好的做法吗?

1 个答案:

答案 0 :(得分:0)

尝试使用 isTerminated() 而不是isShutoown()。但最好的选择是使用 awaitTermination() 方法而不是创建此循环。