如何在不关闭Executor的情况下等待ThreadPoolExecutor中的所有任务完成?

cot*_*aws 60 java multithreading android wait threadpoolexecutor

我无法使用shutdown(),awaitTermination()因为有可能在等待时将新任务添加到ThreadPoolExecutor中.

所以我正在寻找一种方法,等待ThreadPoolExecutor清空它的队列并完成所有任务而不停止在该点之前添加新任务.

如果它有任何区别,这适用于Android.

谢谢

更新:几周后重新访问后,我发现在这种情况下修改后的CountDownLatch对我来说效果更好.我会保留答案标记,因为它更适用于我的要求.

Tim*_*der 69

如果您有兴趣知道某个任务何时完成,或者某一批任务,您可以使用ExecutorService.submit(Runnable).调用此方法会返回一个Future对象,该对象可能会被置于一个Collection主线程将遍历调用Future.get()每个对象的对象中.这将导致主线程停止执行,直到ExecutorService处理完所有Runnable任务.

Collection<Future<?>> futures = new LinkedList<Future<?>>();
futures.add(executorService.submit(myRunnable));
for (Future<?> future:futures) {
    future.get();
}
Run Code Online (Sandbox Code Playgroud)

  • +1,或对一批任务使用invokeAll(),等待完成.请参阅我的回答:http://stackoverflow.com/questions/3269445/executorservice-how-to-wait-for-all-tasks-to-finish/3269888 (12认同)
  • +1这似乎是最好的方式.但是,必须在应用程序级别完成提交任务,而不是在执行程序服务级别. (2认同)

小智 7

我的场景是一个网络爬虫,用于从网站获取一些信息然后处理它们.ThreadPoolExecutor用于加速进程,因为可以在时间加载许多页面.因此,将在现有任务中创建新任务,因为爬网程序将跟随每个页面中的超链接.问题是一样的:主线程不知道所有任务何时完成,并且可以开始处理结果.我用一种简单的方法来确定这一点.它不是很优雅,但在我的情况下工作:

while (executor.getTaskCount()!=executor.getCompletedTaskCount()){
    System.err.println("count="+executor.getTaskCount()+","+executor.getCompletedTaskCount());
    Thread.sleep(5000);
}
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)


Thi*_*ilo 5

也许您正在寻找一个CompletionService来管理批量任务,另请参阅此答案.