Quelle est la différence entre le get()
y join()
les méthodes de la CompletableFuture<T>
classe ?
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 pas de différence dans le résultat.
18 votes
get()
exige que vous attrapiez les exceptions vérifiées. Vous devriez remarquer la différence lorsque vous passez deget()
àjoin()
car vous obtiendrez immédiatement une erreur du compilateur indiquant que ni l'un ni l'autre des éléments suivants n'a été utilisé.InterruptedException
niExecutionException
sont jetés dans letry
bloc.9 votes
@holi-java :
join()
ne peut être interrompu.0 votes
@Holger oui, monsieur. J'ai constaté que je ne pouvais pas interrompre la tâche.
0 votes
@Holger, Merci pour votre réponse et vous avez raison, get attend une exception vérifiée et la méthode join ne l'est pas. Mais les deux attendent de compléter tous les futurs et j'aimerais savoir laquelle je dois utiliser et pourquoi ?
16 votes
Bien
get
existe, carCompletableFuture
met en œuvre leFuture
qui l'impose.join()
a très probablement été introduit pour éviter d'avoir à attraper des exceptions vérifiées dans les expressions lambda lors de la combinaison de contrats à terme. Dans tous les autres cas d'utilisation, n'hésitez pas à utiliser ce que vous préférez.3 votes
Est-il vraiment judicieux d'utiliser join ou get car les deux bloquent le fil. Ne pouvons-nous pas plutôt rendre cela asynchrone en utilisant d'autres méthodes de composition pour créer une chaîne de fonctions asynchrones ? Mais dans le cas, par exemple, d'une méthode de service dans Spring appelée par une méthode de contrôleur renvoyant un futur achevable, il est plus logique de ne pas appeler get ou join dans la méthode de service, n'est-ce pas ?