Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ForkJoinTask vs CompletableFuture

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?

like image 615
thecoop Avatar asked Nov 26 '15 17:11

thecoop


People also ask

What is the difference between future and CompletableFuture?

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.

What is difference between executor framework and ForkJoinPool?

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.

Why is CompletableFuture used?

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.

How is fork join different than executor service?

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.


2 Answers

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

like image 151
Sleiman Jneidi Avatar answered Sep 20 '22 05:09

Sleiman Jneidi


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.

like image 29
Alex Guerreiro Avatar answered Sep 19 '22 05:09

Alex Guerreiro