ゲームに少し遅れますが、完了のために...
すべてのタスクが完了するのを「待つ」のではなく、ハリウッドの原則として、「私に電話しないで、私はあなたに電話する」と考えることができます。結果のコードはよりエレガントだと思います...
グアバはこれを達成するためのいくつかの興味深いツールを提供しています。
例 ::
ExecutorServiceをListeningExecutorServiceにラップする::
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
実行可能な呼び出し可能オブジェクトのコレクションを送信します::
for (Callable<Integer> callable : callables) {
  ListenableFuture<Integer> lf = service.submit(callable);
  // listenableFutures is a collection
  listenableFutures.add(lf)
});
今重要な部分: 
ListenableFuture<List<Integer>> lf = Futures.successfulAsList(listenableFutures);
すべてのフューチャーが完了したときに通知を受けるために使用できるListenableFutureにコールバックをアタッチします::
        Futures.addCallback(lf, new FutureCallback<List<Integer>>() {
        @Override
        public void onSuccess(List<Integer> result) {
            log.info("@@ finished processing {} elements", Iterables.size(result));
            // do something with all the results
        }
        @Override
        public void onFailure(Throwable t) {
            log.info("@@ failed because of :: {}", t);
        }
    });
これには、処理が完了すると、すべての結果を1か所で収集できるという利点もあります...
詳細はこちら