Was ist der Unterschied zwischen CompletableFuture.get()
und CompletableFuture.join()
?
Unten ist mein Code:
List<String> process() {
List<String> messages = Arrays.asList("Msg1", "Msg2", "Msg3", "Msg4", "Msg5", "Msg6", "Msg7", "Msg8", "Msg9",
"Msg10", "Msg11", "Msg12");
MessageService messageService = new MessageService();
ExecutorService executor = Executors.newFixedThreadPool(4);
List<String> mapResult = new ArrayList<>();
CompletableFuture<?>[] fanoutRequestList = new CompletableFuture[messages.size()];
int count = 0;
for (String msg : messages) {
CompletableFuture<?> future = CompletableFuture
.supplyAsync(() -> messageService.sendNotification(msg), executor).exceptionally(ex -> "Error")
.thenAccept(mapResult::add);
fanoutRequestList[count++] = future;
}
try {
CompletableFuture.allOf(fanoutRequestList).get();
//CompletableFuture.allOf(fanoutRequestList).join();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mapResult.stream().filter(s -> !s.equalsIgnoreCase("Error")).collect(Collectors.toList());
}
Ich habe es mit beiden Methoden versucht, aber ich sehe keinen Unterschied im Ergebnis.
java
java-8
completable-future
Nomeswaran
quelle
quelle
get()
erfordert, dass Sie geprüfte Ausnahmen abfangen. Sie sollten den Unterschied bemerken, wenn Sie vonget()
nach wechselnjoin()
, da Sie sofort einen Compilerfehler erhalten, der besagt, dass wederInterruptedException
nochExecutionException
in dentry
Block geworfen werden .join()
kann nicht unterbrochen werden.get
existiert, weilCompletableFuture
implementiert dieFuture
Schnittstelle, die es vorschreibt.join()
höchstwahrscheinlich wurde eingeführt, um zu vermeiden, dass beim Kombinieren von Futures geprüfte Ausnahmen in Lambda-Ausdrücken abgefangen werden müssen. In allen anderen Anwendungsfällen können Sie alles verwenden, was Sie bevorzugen.Antworten:
Der einzige Unterschied besteht darin, wie Methoden Ausnahmen auslösen.
get()
wird in derFuture
Schnittstelle als deklariertV get() throws InterruptedException, ExecutionException;
Die Ausnahmen sind beide geprüfte Ausnahmen, was bedeutet, dass sie in Ihrem Code behandelt werden müssen. Wie Sie in Ihrem Code sehen können, fragte ein automatischer Codegenerator in Ihrer IDE, ob Sie in Ihrem Namen einen Try-Catch-Block erstellen sollen.
try { CompletableFuture.allOf(fanoutRequestList).get() } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); }
Die
join()
Methode löst keine geprüften Ausnahmen aus.public T join()
Stattdessen wird eine ungeprüfte CompletionException ausgelöst. Sie benötigen also keinen Try-Catch-Block, sondern können die
exceptionally()
Methode bei Verwendung der Disscused-List<String> process
Funktion vollständig nutzenCompletableFuture<List<String>> cf = CompletableFuture .supplyAsync(this::process) .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException .thenAccept(this::processFurther);
Beides
get()
und diejoin()
Implementierung finden Sie hierquelle