Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread vs CompletableFuture

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});  
like image 983
Sagar Avatar asked Apr 16 '18 19:04

Sagar


People also ask

Is CompletableFuture a thread?

Yes! CompletableFuture executes these tasks in a thread obtained from the global ForkJoinPool. commonPool(). But hey, you can also create a Thread Pool and pass it to runAsync() and supplyAsync() methods to let them execute their tasks in a thread obtained from your thread pool.

Are CompletableFuture thread safe?

CompletableFuture is inherently thread-safe The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation.

What is difference between ExecutorService and CompletableFuture?

The ExecutorService executes a task and updates the result in the Future. A CompletableFuture introduced later in Java 8 implements the Future interface. So CompletableFuture contains all the functionalities provided by the Future interface. The CompletableFuture allows you to chain tasks together.

What is the difference between future and CompletableFuture?

The Future interface doesn't provide a lot of features, we need to get the result of asynchronous computation using the get() method, which is blocked, so there is no scope to run multiple dependent tasks in a non-blocking fashion whereas CompleteFuture class can provide the functionality to chain multiple dependent ...


2 Answers

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.

like image 199
Gerald Mücke Avatar answered Sep 18 '22 13:09

Gerald Mücke


@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.

like image 36
Hearen Avatar answered Sep 21 '22 13:09

Hearen