0

J'ai une situation où j'ai besoin d'implémenter une récursivité avec CompletableFuture. Je veux appeler recursionFuture(ex) chaque fois que l'un des CompletableFuture s renvoie n'importe quel résultat mais je ne suis pas sûr de savoir comment l'implémenter. Dans la situation actuelle, recursionFuture(ex) est appelée uniquement lorsque future1 et future2 renvoient la sortie, puis si la condition est vérifiée. Toute aide serait appréciée.Comment procéder avec CompletableFuture sans attendre la sortie

public static void recursionFuture(ExecutorService ex) 
    { 
     try 
     { 
      CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex); 
      CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex); 

      if (future1.get() != null | future2.get() != null) 
      { 
       System.out.println("Future1: " + future1.get() + " Future2: " + future2.get()); 
       recursionFuture(ex); 
      } 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

Répondre

1

Vous pouvez combiner avec anyOf()thenRun() pour y parvenir. Il suffit de ne pas appeler get() sur les deux contrats à terme, car cela fait attendre votre programme pour l'achèvement. Vous pouvez utiliser isDone() pour vérifier si un avenir est terminé avant d'appeler get().

CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex); 
CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> new ConcurrencyPoC_CompletableFuture().executeTask(), ex); 

CompletableFuture.anyOf(future1, future2).thenRun(() -> { 
    if (future1.isDone()) { 
     System.out.println("Future 1: " + future1.get()); 
    } 
    if (future2.isDone()) { 
     System.out.println("Future 2: " + future2.get()); 
    } 
    recursionFuture(ex); 
}); 

anyOf() va créer un nouvel avenir qui complétera dès que l'un des contrats à terme fournis a terminé. thenRun() exécutera le Runnable donné dès que le futur appelé est terminé.

+0

Merci Andrew, cela fonctionne mais il y a un petit problème. en raison de la récursivité, le code continue même si le executeTask() ne renvoie rien et continue indéfiniment. Est-il possible de mettre une vérification sur la sortie du futur comme futire1.get()! = Null puis appel récursion mais avec le problème indiqué plus tôt se produit. Pouvez-vous conseiller ici s'il vous plaît. –

+0

Eh bien, je suis arrivé ce travail par l'édition de code comme: CompletableFuture.anyOf (avenir1, avenir2) .thenRunAsync (() -> \t \t \t { \t \t \t \t recursionFuture (ex); \t \t \t} \t \t \t \t \t, ex); –

0

Si vous utilisez uniquement deux CompletableFutures, vous pouvez également consulter runAfterEither/runAfterEitherAsync. Il existe également des versions qui permettent d'accéder à la valeur retournée comme acceptEither/acceptEitherAsync.