web-dev-qa-db-fra.com

ExecutorService.submit (tâche) vs CompletableFuture.supplyAsync (tâche, exécuteur)

Pour exécuter certaines tâches en parallèle ou de manière asynchrone, je peux utiliser un ExecutorService: <T> Future<T> submit(Runnable task, T result); ou l'API CompletableFuture: static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor);

Outre le type de retour Future contre CompletableFuture, existe-t-il des différences remarquables. Ou quand utiliser quoi?

Et quelles sont les différences si j'utilise l'API CompletableFuture avec la valeur par défaut Executor (la méthode sans exécuteur)?

21
dermoritz

Outre le type de retour Future vs. CompletableFuture, existe-t-il des différences remarquables. Ou quand utiliser quoi?

C'est plutôt simple, vraiment. Vous utilisez la variable Future lorsque vous souhaitez que le thread en cours d'exécution attende une réponse de calcul asynchrone. Un exemple de ceci est avec une fusion/tri parallèle. Triez à gauche de manière asynchrone, triez à droite de manière synchrone, attendez à gauche pour terminer (future.get()), fusionnez les résultats.

Vous utilisez un CompleteableFuture lorsque vous souhaitez qu'une action soit exécutée, avec le résultat après achèvement, de manière asynchrone à partir du thread exécuté. Par exemple, je souhaite effectuer des calculs de manière asynchrone et lorsque je calcule, écris les résultats sur un système. Le thread demandeur peut alors ne pas avoir besoin d'attendre un résultat.

Vous pouvez imiter l'exemple ci-dessus dans un seul exécutable Future, mais CompletableFuture offre une interface plus fluide avec une meilleure gestion des erreurs.

Cela dépend vraiment de ce que vous voulez faire.

Et quelles sont les différences si j'utilise CompletableFutureApi avec Executor par défaut (la méthode sans exécuteur)?

Il déléguera à ForkJoin.commonPool() qui est une taille par défaut pour le nombre de processeurs de votre système. Si vous effectuez une opération IO intensive (lecture et écriture dans le système de fichiers), vous devez définir le pool de threads différemment.

Si vous utilisez beaucoup de ressources en processeur, utilisez le pool commun.

19
John Vint

CompletableFuture possède de riches fonctionnalités telles que le chaînage de plusieurs futures, la combinaison des futures, l'exécution de certaines actions après l'exécution future (à la fois de manière synchrone et asynchrone), etc.

Cependant, CompletableFuture n’est pas différent de Future en termes de performances. Même en combinant plusieurs instances de CompletableFuture (en utilisant .thenCombine et .join à la fin), aucune d'entre elles n'est exécutée à moins d'appeler la méthode .get et, pendant ce temps, le thread appelant est bloqué. Je pense qu'en termes de performance, ce n'est pas mieux que Future. 

Faites-moi savoir s'il me manque un aspect de la performance ici.

1
Chinmay Phadke

Cela m'a permis de clarifier un peu plus la différence entre futur et completable: Différence entre futur et promesse

CompletableFuture est plus comme une promesse.

0
dermoritz