web-dev-qa-db-fra.com

Thread vs CompletableFuture

Quel est l'avantage de passer du code directement au thread par rapport à l'utilisation de CompletableFuture à la place?

Thread thread = new Thread(() -> {do something});
thread.start();

CONTRE

CompletableFuture<Void> cf1 =  
     CompletableFuture.runAsync(() -> {do something}); 
15
Sagar

CompletableFuture.runAsync(...) exécute le Runnable dans le forkJoin-Pool qui est géré, tandis que new Thread() crée un nouveau thread qui vous devez gérer .

Qu'est-ce que "est géré" signifie, il est pré-alloué et les threads sont partagés dans la JVM. Lorsque le runnable est terminé, le thread peut être réutilisé pour d'autres runnables. Cela permet une meilleure utilisation des ressources, d'autant plus que l'instanciation de threads est une opération coûteuse - non seulement l'objet, mais aussi une mémoire supplémentaire non-tas - la pile de threads - doit être allouée.

14
Gerald Mücke

@Gerald Mücke a déjà mentionné la différence importante:

CompletableFuture.runAsync (...) exécute le Runnable dans le forkJoin-Pool qui est géré, tandis que new Thread () crée un nouveau thread que vous devez gérer.

CompletableFuture utilisera des threads gérés par un ThreadPool (par défaut ou personnalisé).

Cependant, je pense que les deux points suivants sont également à considérer.

Première

CompletableFuture a tellement de méthodes facilement compréhensibles pour chaîne différents calculs asynchrones ensemble, ce qui rend beaucoup plus facile l'introduction de l'asynchronie que l'utilisation directe de Thread.

CompletableFuture[] futures = IntStream.rangeClosed(0, LEN).boxed()
            .map(i -> CompletableFuture.supplyAsync(() -> runStage1(i), EXECUTOR_SERVICE))
            .map(future -> future.thenCompose(i -> CompletableFuture.supplyAsync(() -> runStage2(i), EXECUTOR_SERVICE)))
            .toArray(size -> new CompletableFuture[size]);
CompletableFuture.allOf(futures).join();

Seconde

Vous ne devez jamais oublier de gérer exceptions; avec CompletableFuture, vous pouvez les gérer directement comme ceci:

completableFuture.handle((s, e) -> e.toString()).join()

ou profitez-en pour interrompre le calcul:

completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));

alors que vous rencontrerez facilement de graves problèmes en utilisant Thread.

3
Hearen