Ein bisschen spät zum Spiel, aber der Vollendung halber ...
Anstatt darauf zu warten, dass alle Aufgaben erledigt sind, können Sie nach dem Hollywood-Prinzip denken: "Rufen Sie mich nicht an, ich rufe Sie an" - wenn ich fertig bin. Ich denke, der resultierende Code ist eleganter ...
Guave bietet einige interessante Werkzeuge, um dies zu erreichen.
Ein Beispiel ::
Wickeln Sie einen ExecutorService in einen ListeningExecutorService ::
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
Senden Sie eine Sammlung von Callables zur Ausführung ::
for (Callable<Integer> callable : callables) {
ListenableFuture<Integer> lf = service.submit(callable);
// listenableFutures is a collection
listenableFutures.add(lf)
});
Nun zum wesentlichen Teil:
ListenableFuture<List<Integer>> lf = Futures.successfulAsList(listenableFutures);
Fügen Sie der ListenableFuture einen Rückruf hinzu, mit dem Sie benachrichtigt werden können, wenn alle Futures abgeschlossen sind:
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);
}
});
Dies bietet auch den Vorteil, dass Sie alle Ergebnisse nach Abschluss der Verarbeitung an einem Ort sammeln können ...
Weitere Informationen hier