等待 ExecutorService
的所有任务完成的最简单方法是什么?我的任务主要是计算性的,所以我只想运行大量作业——每个核心一个。现在我的设置如下所示:
ExecutorService es = Executors.newFixedThreadPool(2);
for (DataTable singleTable : uniquePhrases) {
es.execute(new ComputeDTask(singleTable));
}
try{
es.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
ComputeDTask
实现可运行。这似乎可以正确执行任务,但代码在 wait()
和 IllegalMonitorStateException
上崩溃。这很奇怪,因为我尝试了一些玩具示例并且它似乎有效。
uniquePhrases
包含数万个元素。我应该使用另一种方法吗?我正在寻找尽可能简单的东西
原文由 george smiley 发布,翻译遵循 CC BY-SA 4.0 许可协议
最简单的方法是使用
ExecutorService.invokeAll()
它可以在单行中执行您想要的操作。用你的话说,你需要修改或包装ComputeDTask
来实现Callable<>
,这可以给你更多的灵活性。可能在您的应用程序中有Callable.call()
的有意义的实现,但如果不使用Executors.callable()
--- ,这里有一种包装它的方法。正如其他人指出的那样,如果合适,您可以使用
invokeAll()
的超时版本。在此示例中,answers
将包含一堆Future
将返回空值(参见Executors.callable()
的定义)。轻微重构,以便您可以获得有用的答案,或对底层ComputeDTask
的引用,但我无法从您的示例中看出。如果不清楚,请注意
invokeAll()
在所有任务完成之前不会返回。 (即,您的answers
集合中的所有Future
s 将报告.isDone()
如果被问到的话。)这避免了所有手动关机等的终止…如果需要,允许您在多个周期中整齐地重复使用这个ExecutorService
。SO 上有几个相关问题:
如何等待所有线程完成
从 Java 线程返回值
invokeAll() 不愿意接受 Collection>
我需要同步吗?
这些都不是严格针对您的问题,但它们确实提供了一些关于人们如何思考的颜色
Executor
/ExecutorService
应该被使用。