5

我有以下代码散列:

public class MyCallable implements Callable<Long> {
    @Override
    public Long call() throws Exception {
        // Do stuff...
    }
}

public class MyController {
    private ExecutorService executor = Executos.newCachedTreadPool();

    public Long concurrentDoStuff() {
        List<MyCallable> workers = makeWorkers();

        List<Long> allResults = new ArrayList<Long>();
        for(MyCallable worker : workers) {
            Future<Long> workerResults = executor.submit(worker);

            try {
                allResults.add(workerResults.get());
            } catch(InterruptedException ie) {
                // Handle...
            } catch(ExecutionException ee) {
                // Handle...
            }
        }

        // Question: how do I pause here and wait for all workers to finish?
    }
}

for循环之后,我想等待所有工作人员完成后再继续。最好/最安全/最有效的方法是什么?提前致谢!

4

4 回答 4

5

使用CountDownLatch

  • 用工人的数量初始化它
  • 在工作构造函数中传递对闩锁的引用
  • 工作人员完成后,调用countDown
  • 调用await主线程,它将阻塞,直到工作人员完成。

这是一个比在 executor 服务上使用方法更通用的解决方案。

于 2013-05-10T13:24:01.973 回答
4

您必须使用 关闭执行器shutDown,然后等到所有作业都已处理完毕awaitTermination

于 2013-05-10T13:21:01.310 回答
4

您可以致电:

executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE , TimeUnit.NANOSECONDS);

这将(几乎)无限期地等待任务完成。

于 2013-05-10T13:22:20.383 回答
1

有一个方便的方法。

ExecutorService.invokeAll(List<Callable> callables);

它将返回List<Future>对象,以便您可以获取所有单个call()方法的返回对象。

ExecutorService您可以通过调用获取实例Executors.new....()

于 2013-05-11T01:53:34.120 回答