等待线程池中所有工作程序完成的最佳方法是什么?

时间:2015-03-07 06:01:23

标签: java multithreading

想象一下,我有以下代码:

final ExecutorService threadPool = Executors.newFixedThreadPool(
    NUMBER_OF_WORKERS);

for (int i=0; i < NUMBER_OF_WORKERS; i++)
{
  final Worker worker = new BirthWorker(...);
  threadPool.execute(worker);
}

现在我需要一段代码,等待所有工人完成工作。

我意识到的选项:

  1. while (!threadPool.isTerminated()) {}
  2. 修改代码:

    final List futures = new ArrayList(NUMBER_OF_WORKERS); final ExecutorService threadPool = Executors.newFixedThreadPool(NUMBER_OF_WORKERS);

    for(int i = 0; i&lt; NUMBER_OF_WORKERS; i ++) {   最终工人=新工人(...);   futures.add(threadPool.submit(工人)); }

    for(最后未来未来:期货){     的Future.get(); }

    //当我们到达这里时,所有工人都可以保证完成他们的工作。

  3. 等待所有工人完成的最佳做法是什么?

3 个答案:

答案 0 :(得分:3)

我建议您使用CountDownLatch(假设这是一次性活动),在构造函数中,您可以指定要等待的线程数,然后在线程中共享该实例并等待所有线程使用await api(使用超时或完全阻塞)完成的线程以及线程在完成后调用countdown api。

另一种选择是,如果你有权访问你希望完成的每一个线程,在线程中调用join方法等待它们的完成。

答案 1 :(得分:2)

我会使用ThreadPoolExecutor.invokeAll(Collection<? extends Callable<T>> tasks)

API:执行给定的任务,在完成所有操作后返回持有其状态和结果的Futures列表

答案 2 :(得分:1)

如上所述,CountDownLatch可以很好地完成工作,请记住,您想在完成后关闭执行程序:

final ExecutorService threadPool = Executors.newFixedThreadPool(
NUMBER_OF_WORKERS);

for (int i=0; i < NUMBER_OF_WORKERS; i++)
{
  final Worker worker = new BirthWorker(...);
  threadPool.execute(worker);
}
threadPool.shutdown();

除非你关闭它,否则即使所有工人都完成了,threadPool.isTerminated也会保持为假。