192 votes

Classe CompletableFuture<T> : join() vs get()

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 de get() à 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 ni ExecutionException sont jetés dans le try 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.

195voto

Dawid Wróblewski Points 501

La seule différence réside dans la manière dont les méthodes lancent des exceptions. get() est déclarée dans Future comme :

V get() throws InterruptedException, ExecutionException;

Les exceptions sont à la fois vérifié 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 automatique de code dans votre IDE a demandé de 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();
}

En join() ne lance pas de vérifié exceptions.

public T join()

Au lieu de cela, il lance non vérifié CompletionException . Vous n'avez donc pas besoin d'un bloc try-catch, mais vous pouvez exploiter pleinement la fonction exceptionally() lors de l'utilisation de la méthode disscused List<String> process fonction

CompletableFuture<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() y join() mise en œuvre aquí .

22voto

Praj Points 71

En plus de la réponse fournie par Dawid, la méthode get est disponible en deux versions :

get()
get(Long timeout, TimeUnit timeUnit) 

Le deuxième obtenir prend le temps d'attente comme argument et attend au maximum le temps d'attente fourni.

try {
    System.out.println(cf.get(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
    ex.printStackTrace();
}

Vous pouvez vous référer à cette documentation pour plus d'informations.

  1. join() est défini dans CompletableFuture alors que get() provient de l'interface Future
  2. join() lève une exception non vérifiée alors que get() lève des exceptions vérifiées
  3. Vous pouvez interrompre get() et ensuite lancer une Exception Interrompue.
  4. La méthode get() permet de spécifier le temps d'attente maximum

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X