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

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

相关内容

  • 没有找到相关文章

最新更新