2017-02-16 4 views
2

J'ai ce cas où il y a 10 tâches ou plus qui sont groupées en plusieurs groupes. A l'intérieur de ces groupes, tout doit fonctionner simultanément, mais comme chaque groupe a besoin des résultats du groupe précédent (à l'exception du premier groupe), je dois les exécuter de manière ordonnée (les tâches à l'intérieur d'un groupe n'ont pas besoin de fonctionner).Commandé l'exécution de plusieurs CompletableFuture.allof() tout en restant non bloquant

Les tâches elles-mêmes interrogent des données à partir de la base de données, puis appliquent une transformation et les sauvegardent dans la base de données.

Task 1.1 // This group run first 
Task 1.2 

Task 2.1 // Waiting results from group 1 
Task 2.2 
Task 2.3 

Task 3.1 // Waiting results from group 2 

Je pensais à utiliser la liste des allOf(), itérer-il alors appeler explicitement get() pour chacun qui allOf(), mais il bloquera que je ne veux pas que cela se produise, donc ma question est, comment exécuter beaucoup allOf() dans l'ordre? Est-ce que iteven est possible d'utiliser seulement CompletableFuture ici?

Répondre

1

Lorsque vous utilisez allOf(), il renvoie un CompletableFuture qui se termine uniquement lorsque toutes les étapes d'achèvement données sont terminées.

Si vous enchaînez les appels à partir du futur renvoyé, ils sont ainsi assurés qu'un appel à get() sur l'une des étapes d'achèvement passées à allOf() ne sera jamais bloqué (car ils sont déjà terminés).

// First group 
CompletableFuture<Integer> task11 = CompletableFuture.supplyAsync(() -> 1); 
CompletableFuture<Integer> task12 = CompletableFuture.supplyAsync(() -> 42); 
CompletableFuture<Integer> task13 = CompletableFuture.supplyAsync(() -> 1729); 

// this one will complete after all tasks from the first group complete 
CompletableFuture<Void> allFirstTasks = CompletableFuture.allOf(task11, task12, task13); 

// Second group will be child tasks from the first group 
CompletableFuture<Integer> task21 = allFirstTasks.thenApply(__ -> 
     task11.join() + task12.join() + task13.join() // will not block 
); 

Note: L'utilisation join() au lieu de get() pour éviter la manipulation des exceptions vérifiées.