In Java 8 there are two ways of starting asynchronous computations - CompletableFuture
and ForkJoinTask
. They both seem fairly similar - the inner classes of CompletableFuture
even extend ForkJoinTask
.
Is there a reason to use one over the other?
One key difference that I can see is that the CompletableFuture.join
method simply blocks until the future is complete (waitingGet
just spins using a ManagedBlocker
), whereas a ForkJoinTask.join
can steal work off the queue to help the task you're joining on to complete.
Is there a benefit over one or the other?
Future vs CompletableFuture. CompletableFuture is an extension to Java's Future API which was introduced in Java 5. A Future is used as a reference to the result of an asynchronous computation.
In short, the main difference between the Executor framework and ForkJoinPool is that the former provides a general-purpose thread pool, while the latter provides a special implementation that uses a work-stealing pattern for efficient processing of ForkJoinTask.
What is CompletableFuture? A CompltableFuture is used for asynchronous programming. Asynchronous programming means writing non-blocking code. It runs a task on a separate thread than the main application thread and notifies the main thread about its progress, completion or failure.
Fork Join is an implementation of ExecuterService. The main difference is that this implementation creates a DEQUE worker pool. Executor service creates asked number of thread, and apply a blocking queue to store all the remaining waiting task.
They are two different things, ForkJoinTask
is a task that can be submitted to a ForkJoinPool
, CompletableFuture
is a promise that can work with any Executor
and the executor doesn't need to be the ForkJoinPool
,
It is true however that the common ForkJoinPool
is the default if you don't specify any, for ex:
CompletableFuture.supplyAsync(()-> supplier);
uses the ForkJoinPool
if you don't pass an Executor
. There is another overload
that takes an Executor
.
CompletableFuture.supplyAsync(()-> supplier,executor);
Async
,which is a static
class in CompletableFuture
extends ForkJoinTask<Void>
, but it doesn't need to be a ForkJoinTask
, from the docs of Async
/** Base class can act as either FJ or plain Runnable */
abstract static class Async extends ForkJoinTask<Void>
implements Runnable, AsynchronousCompletionTask
It can also a Runnable
and a AsynchronousCompletionTask
Just on side note: ForkJoinTask
, ForkJoinPool
, ForkJoin...
classes were added in 1.7 and not 1.8
I'd say that the ForkJoinTask
is more recommended when you have a big task and want to split it to run in parallel in several sub tasks. The ForkJoin
framework uses the work stealing algorithm which will make an efficient use of the threads. On the other hand, CompletableFutures
are more appropriate for a Reactive programming model, where you can create pipelines of execution in a sync or async fashion, and have a better control of the threads by using the thread pools of the Executor Service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With