java - ExecutorService,如何等待所有任务完成

标签 java multithreading threadpool executorservice

等待 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 包含数以万计的元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西

最佳答案

最简单的方法是使用 ExecutorService.invokeAll() 它可以满足您的需求。用您的话说,您需要修改或包装 ComputeDTask实现Callable<> ,这可以给你更多的灵 active 。可能在您的应用程序中有一个有意义的 Callable.call() 实现。 , 但如果不使用 Executors.callable() .

ExecutorService es = Executors.newFixedThreadPool(2);
List<Callable<Object>> todo = new ArrayList<Callable<Object>>(singleTable.size());

for (DataTable singleTable: uniquePhrases) { 
    todo.add(Executors.callable(new ComputeDTask(singleTable))); 
}

List<Future<Object>> answers = es.invokeAll(todo);

正如其他人所指出的,您可以使用 invokeAll() 的超时版本如果合适的话。在本例中,answers将包含一堆 Future s 将返回空值(请参阅 Executors.callable() 的定义。可能您想要做的是轻微的重构,以便您可以得到有用的答案,或者对底层 ComputeDTask 的引用,但我无法从您的例子。

如果不清楚,请注意 invokeAll()在完成所有任务之前不会返回。 (即,如果询问,您的 Future 集合中的所有 answers 将报告 .isDone()。)这避免了所有手动关闭、awaitTermination 等...并允许您重用此 ExecutorService如果需要,可以整齐地进行多个循环。

关于 SO 有几个相关的问题:

这些都不是你的问题的严格点,但它们确实为人们的想法提供了一些色彩Executor/ExecutorService应该使用。

关于java - ExecutorService,如何等待所有任务完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3269445/

相关文章:

java - 了解 wait() 和 notify() 方法

java - BasicThreadPool 在 J-boss 7.1 中不可用

java - cachedThreadPool 没有按我的预期工作

java - Spring文件上传内容类型验证,总是八位字节流?

java - java中如何比较两个ArrayList

java - oracle java教程中可能有错误?

java - 使用同步方法而不是同步块(synchronized block)有优势吗?

java - 如何使用 imgscalr 将文本添加到图像

c++ - 在线程中使用原子变量

java - ExecutorService 中的持久变量 (Java)