且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2021-10-21 09:08:10

最简单的方法是使用 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 将返回空值(参见 Executors.callable() 的定义.可能你想要做的是轻微的重构,这样你就可以得到一个有用的答案,或者对底层 ComputeDTask 的引用,但我无法从你的例子中看出.

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 Futures 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() 直到所有任务都完成后才会返回.(即,如果询问,answers 集合中的所有 Future 将报告 .isDone().)这避免了所有手动关闭,awaitTermination等...并允许您根据需要在多个循环中巧妙地重用此 ExecutorService.

If it isn't clear, note that invokeAll() will not return until all the tasks are completed. (i.e., all the Futures 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:

从 Java 线程返回值

invokeAll() 不愿意接受一个集合<可调用>

我可以吗需要同步吗?

这些都不是严格针对您的问题,但它们确实提供了一些关于人们认为应该如何使用 Executor/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.