Quelle est la différence entre CompletableFuture.get()
et CompletableFuture.join()
?
Voici mon 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());
}
J'ai essayé les deux méthodes mais je ne vois aucune différence de résultat.
java
java-8
completable-future
Nomeswaran
la source
la source
get()
vous oblige à intercepter les exceptions vérifiées. Vous devriez remarquer la différence lorsque vous passez deget()
àjoin()
, car vous obtiendrez immédiatement une erreur de compilation indiquant que niInterruptedException
ni neExecutionException
sont jetés dans letry
bloc.join()
ne peut pas être interrompu.get
existe, carCompletableFuture
implémente l'Future
interface qui le commande.join()
le plus probable a été introduit, pour éviter d'avoir à intercepter les exceptions vérifiées dans les expressions lambda lors de la combinaison de futures. Dans tous les autres cas d'utilisation, n'hésitez pas à utiliser ce que vous préférez.Réponses:
la seule différence est la façon dont les méthodes lancent des exceptions.
get()
est déclaré dans l'Future
interface commeV get() throws InterruptedException, ExecutionException;
Les exceptions sont toutes deux vérifiées, ce qui signifie qu'elles doivent être gérées dans votre code. Comme vous pouvez le voir dans votre code, un générateur de code automatique dans votre IDE vous a demandé s'il fallait créer un bloc try-catch en votre nom.
try { CompletableFuture.allOf(fanoutRequestList).get() } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); }
La
join()
méthode ne lève pas d' exceptions vérifiées .public T join()
Au lieu de cela, il lance une exception CompletionException non vérifiée. Vous n'avez donc pas besoin d'un bloc try-catch et à la place, vous pouvez pleinement exploiter la
exceptionally()
méthode lors de l'utilisation de laList<String> process
fonction dissociéeCompletableFuture<List<String>> cf = CompletableFuture .supplyAsync(this::process) .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException .thenAccept(this::processFurther);
Vous pouvez trouver les deux
get()
et lajoin()
mise en œuvre icila source