Ausgabe
Ich habe eine Methode, die a List
von Futures zurückgibt
List<Future<O>> futures = getFutures();
Jetzt möchte ich warten, bis entweder alle Futures erfolgreich verarbeitet wurden oder eine der Aufgaben, deren Ausgabe von einem Future zurückgegeben wird, eine Ausnahme auslöst. Selbst wenn eine Aufgabe eine Ausnahme auslöst, macht es keinen Sinn, auf die anderen Futures zu warten.
Einfacher Ansatz wäre zu
wait() {
For(Future f : futures) {
try {
f.get();
} catch(Exception e) {
//TODO catch specific exception
// this future threw exception , means somone could not do its task
return;
}
}
}
Aber das Problem hier ist, wenn zum Beispiel der 4. Future eine Ausnahme auslöst, dann werde ich unnötig warten, bis die ersten 3 Futures verfügbar sind.
Wie löst man das? Wird der Countdown-Latch in irgendeiner Weise helfen? Ich kann Future nicht verwenden, isDone
weil das Java-Dokument sagt
boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.
Lösung
Sie können einen CompletionService verwenden , um die Futures zu erhalten, sobald sie bereit sind, und wenn einer von ihnen eine Ausnahme auslöst, die Verarbeitung abzubrechen. Etwas wie das:
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<SomeResult> completionService =
new ExecutorCompletionService<SomeResult>(executor);
//4 tasks
for(int i = 0; i < 4; i++) {
completionService.submit(new Callable<SomeResult>() {
public SomeResult call() {
...
return result;
}
});
}
int received = 0;
boolean errors = false;
while(received < 4 && !errors) {
Future<SomeResult> resultFuture = completionService.take(); //blocks if none available
try {
SomeResult result = resultFuture.get();
received ++;
... // do something with the result
}
catch(Exception e) {
//log
errors = true;
}
}
Ich denke, Sie können weiter verbessern, um alle noch ausgeführten Aufgaben abzubrechen, wenn einer von ihnen einen Fehler auslöst.
Beantwortet von – dcernahoschi
Antwort geprüft von – Katrina (FixError Volunteer)