Thread vs CompletableFuture

2020-05-19 04:32发布

问题:

What is the advantage of passing code directly to thread vs using CompletableFuture instead?

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

VS

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

回答1:

CompletableFuture.runAsync(...) runs the Runnable in the forkJoin-Pool which is managed, while new Thread() creates a new thread which you have to manage.

What does "is managed" mean, it's pre-allocated and the threads are shared in the JVM. When the runnable is completed, the thread can be reused for other runnables. This makes better usage of resources, especially as thread instantiation is an expensive operation - not only the object, but also some extra non-heap memory - the thread stack - has to be allocated.



回答2:

@Gerald Mücke already mentioned the important difference:

CompletableFuture.runAsync(...) runs the Runnable in the forkJoin-Pool which is managed, while new Thread() creates a new thread which you have to manage.

CompletableFuture will use threads managed by a ThreadPool (default or customized).

However, I think the following two points are also should be considered.

First

CompletableFuture has so many easily understandable methods to chain different asynchronous computations together, making it much easier to introduce asynchrony than directly using 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();

Second

You should never forget to handle exceptions; with CompletableFuture, you can directly handle them like this:

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

or take advantage of them this way to interrupt the computation:

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

while you will easily encounter some serious problems using Thread.