ExecutorService,如何等待所有任务完成 [英] ExecutorService, how to wait for all tasks to finish
问题描述
等待 ExecutorService
的所有任务完成的最简单方法是什么?我的任务主要是计算,所以我只想运行大量的工作 - 每个核心一个。现在我的设置如下所示:
What is the simplest way to to wait for all tasks of ExecutorService
to finish? My task is primarily computational, so I just want to run a large number of jobs - one on each core. Right now my setup looks like this:
ExecutorService es = Executors.newFixedThreadPool(2);
for (DataTable singleTable : uniquePhrases) {
es.execute(new ComputeDTask(singleTable));
}
try{
es.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
ComputeDTask
实现runnable 。这似乎正确执行任务,但代码在 wait()
上崩溃,并带有 IllegalMonitorStateException
。这很奇怪,因为我玩了一些玩具示例,它似乎工作。
ComputeDTask
implements runnable. This appears to execute the tasks correctly, but the code crashes on wait()
with IllegalMonitorStateException
. This is odd, because I played around with some toy examples and it appeared to work.
uniquePhrases
包含数万个元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西
uniquePhrases
contains several tens of thousands of elements. Should I be using another method? I am looking for something as simple as possible
推荐答案
最简单的方法是使用 ExecutorService.invokeAll()
可以在单行中完成您想要的任务。按照你的说法,你需要修改或包装 ComputeDTask
来实现 Callable<>
,这可以给你相当多的灵活性。可能在你的应用程序中有一个有意义的 Callable.call()
的实现,但如果不使用 Executors.callable( )
。
The simplest approach is to use ExecutorService.invokeAll()
which does what you want in a one-liner. In your parlance, you'll need to modify or wrap ComputeDTask
to implement Callable<>
, which can give you quite a bit more flexibility. Probably in your app there is a meaningful implementation of Callable.call()
, but here's a way to wrap it if not using 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
,它将返回空值(参见<$的定义) c $ c> Executors.callable()。你可能想要做的是轻微的重构,这样你就可以得到一个有用的答案,或者对底层 ComputeDTask <的引用/ code>,但我无法从你的例子中看出。
As others have pointed out, you could use the timeout version of invokeAll()
if appropriate. In this example, answers
is going to contain a bunch of Future
s which will return nulls (see definition of Executors.callable()
. Probably what you want to do is a slight refactoring so you can get a useful answer back, or a reference to the underlying ComputeDTask
, but I can't tell from your example.
如果不清楚,请注意 invokeAll()
在完成所有任务之前不会返回。(即答案中的所有
Future
s $ c如果被问到,$ c> collection将报告 .isDone()
。这可以避免所有手动关机,awaitTermination等...并允许你重复使用 ExecutorService
如果需要,可以整齐地进行多个周期。
If it isn't clear, note that invokeAll()
will not return until all the tasks are completed. (i.e., all the Future
s in your answers
collection will report .isDone()
if asked.) This avoids all the manual shutdown, awaitTermination, etc... and allows you to reuse this ExecutorService
neatly for multiple cycles, if desired.
SO上有一些相关的问题:
There are a few related questions on SO:
invokeAll()不愿意接受集合< Callable< t>>
这些都不是严格意义上的问题,但它们确实提供了一些关于人们如何思考的颜色执行者
/ ExecutorService
应该被使用。
None of these are strictly on-point for your question, but they do provide a bit of color about how folks think Executor
/ExecutorService
ought to be used.
这篇关于ExecutorService,如何等待所有任务完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!