2017-10-05 9 views
-3

J'essaie de réaliser quelque chose comme ça. C'est un exemple inventé qui exprime l'intention.Comment appeler futurable en boucle et combiner tous les résultats?

Je veux que tous les contrats à terme réalisables s'exécutent et combinent tous leurs résultats à un résultat et le retournent. Donc pour l'exemple ci-dessous, la collection allResults doit avoir les chaînes "un", "deux", "trois", 3 fois chacune. Je veux qu'ils courent tous en parallèle et non en série.

Tous les pointeurs vers quelle API sur le futur réalisable que je pourrais utiliser pour réaliser ceci, seraient très utiles.

public class Main { 


    public static void main(String[] args) { 

     int x = 3; 
     List<String> allResuts; 

     for (int i = 0; i < x; i++) { 

      //call getCompletableFutureResult() and combine all the results 
     } 

    } 

    public static CompletableFuture<List<String>> getCompletableFutureResult() { 

     return CompletableFuture.supplyAsync(() -> getResult()); 
    } 

    private static List<String> getResult() { 


     List<String> list = new ArrayList<>(); 
     list.add("one"); 
     list.add("two"); 
     list.add("three"); 

     return list; 
    } 


} 
+0

Définir _combine_. –

Répondre

1

Vous ne pouvez pas collecter les résultats dans la 1ère boucle for, car cela signifie que vous n'êtes même pas commencer les autres tâches en attendant les résultats des tâches précédentes.

Commencez donc à collecter les résultats une fois toutes les tâches démarrées.

public static void main(String[] args) throws Exception 
{ 
    int x = 3; 

    Queue<CompletableFuture<List<String>>> cfs = new ArrayDeque<>(x); 
    for (int i = 0; i < x; i++) 
    { 
    cfs.add(getCompletableFutureResult()); 
    } 

    List<String> allResuts = new ArrayList<>(); 
    for (CompletableFuture<List<String>> cf : cfs) 
    allResuts.addAll(cf.get()); 

    System.out.println(allResuts); 
} 
1

Il y a un problème avec la réponse de Venkata Raju. Raju utilisé obtenir appel sur l'avenir qui est un appel bloquant et tue l'objectif principal du codage dans le style asynchrone. Évitez toujours de faire des contrats à terme.

Il y a des tonnes de méthodes intégrées build autour des valeurs futures de manipulation comme méthode thenApply, thenAccept, thenCompose, thenCombine etc.

CompletableFuture.allOf est destiné à être utilisé lorsque vous devez faire face à de multiples contrats à terme.

Il a cette signature suivante

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) 

Side note:CompletableFuture.anyOf peut être utilisé lorsque vous tenir compte que du premier avenir à remplir. Utilisez allOf lorsque vous avez besoin de tous les contrats à terme à compléter.

Je voudrais coder votre spécification de la manière suivante en utilisant CompletableFuture.allOf.

public class DorjeeTest { 


    public static CompletableFuture<List<String>> getCompetableFutureResult() { 
     return CompletableFuture.supplyAsync(() -> getResult()); 
    } 
    public static List<String> getResult() { 
     return Lists.newArrayList("one", "two", "three"); 
    } 

    public static void testFutures() { 
     int x = 3; 
     List<CompletableFuture<List<String>>> futureResultList = Lists.newArrayList(); 
     for (int i = 0; i < x; i++) { 
      futureResultList.add(getCompetableFutureResult()); 
     } 

     CompletableFuture[] futureResultArray = futureResultList.toArray(new CompletableFuture[futureResultList.size()]); 

     CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureResultArray); 

     CompletableFuture<List<List<String>>> finalResults = combinedFuture 
       .thenApply(voidd -> 
         futureResultList.stream() 
           .map(future -> future.join()) 
         .collect(Collectors.toList())); 

     finalResults.thenAccept(result -> System.out.println(result)); 
    } 


    public static void main(String[] args) { 
     testFutures(); 
     System.out.println("put debug break point on this line..."); 

    } 
}