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.

In this way, the main thread does not block or wait for the completion of the task. Other tasks execute in parallel. Parallelism improves the performance of the program.

A CompletableFuture is a class in Java. It belongs to java.util.cocurrent package. It implements CompletionStage and Future interface.

CompletionStage

  • It performs an action and returns a value when another completion stage completes.
  • A model for a task that may trigger other tasks.

Hence, it is an element of a chain.

When more than one thread attempt to complete - complete exceptionally or cancel a CompletableFuture, only one of them succeeds.

Future vs. CompletableFuture

A CompletableFuture is an extension to Java's Future API which was introduced in Java 8.

A Future is used for asynchronous Programming. It provides two methods, isDone() and get(). The methods retrieve the result of the computation when it completes.

Limitations of the Future

  • A Future cannot be mutually complete.
  • We cannot perform further action on a Future's result without blocking.
  • Future has not any exception handling.
  • We cannot combine multiple futures.

Future has so many limitations, that's why we have CompletableFuture. CompletableFuture provides a broad set of methods for creating multiple Futures, chaining, and combining. It also has comprehensive exception handling support.

Creating a CompletableFuture

We can create a CompletableFuture only by using the following no-argument constructor.

Example

The most frequently used CompletableFuture methods are:

  • supplyAsync(): It complete its job asynchronously. The result of supplier is run by a task from ForkJoinPool.commonPool() as default. The supplyAsync() method returns CompletableFuture on which we can apply other methods.
  • thenApply(): The method accepts function as an arguments. It returns a new CompletableStage when this stage completes normally. The new stage use as the argument to the supplied function.
  • join(): the method returns the result value when complete. It also throws a CompletionException (unchecked exception) if completed exceptionally.

File Name: CompletableFutureExample1.java

Output:

CompletableFuture in Java

Async Methods of CompletableFuture

CompletableFuture provides a set of asynchronous methods that allow for non-blocking operations, enabling the execution of tasks in a separate thread without blocking the caller thread. These methods are essential for developing responsive applications, especially when dealing with I/O-bound tasks, complex computations, or any process whose duration is unpredictable. Here's a summary of some key async methods provided by CompletableFuture:

thenApplyAsync()

The thenApplyAsync() function processes a task's outcome asynchronously, yielding a new CompletableFuture containing the modified result. A distinct thread from the ForkJoinPool.commonPool() carries out this processing, ensuring the operation does not block the calling thread and enhances application responsiveness by leveraging asynchronous execution patterns.

Filename: CompletableFutureExample.java

Output:

Hello, John!

thenAcceptAsync()

The `thenAcceptAsync()` function facilitates the asynchronous consumption of a task's output, where no value is returned. Execution occurs on an independent thread from the `ForkJoinPool.commonPool()`, ensuring that the main workflow remains uninterrupted by this process.

Filename: ThenAcceptAsyncExample.java

Output:

User Score: 85

runAsync()

The runAsync() function facilitates the execution of a task in an asynchronous manner, where no return value is expected. Execution is carried out on an independent thread within the ForkJoinPool.commonPool(), ensuring the task does not interrupt the main workflow.

Filename: RunAsyncExample.java

Output:

This is an asynchronous task running in a separate thread.
Asynchronous task completed.

CompletableFsutrue Class Methods

Modifier and TypeMethod and Description
CompletableFuture<Void>acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action)
Generates a new CompletionStage which, upon normal completion of either the current stage or another specified stage, triggers the execution of a provided action using the outcome of the first completed stage as its input.
CompletableFuture<Void>acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action)
Creates a fresh `CompletionStage` set to execute a given action asynchronously through the default execution mechanism of this stage, once either the current or an alternative specified stage finishes successfully, using the result of the first to complete as the action's input.
CompletableFuture<Void>acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor)
Produces a new `CompletionStage` which, upon the normal completion of either the current stage or a specified alternative stage, carries out the provided function asynchronously, utilizing a designated executor, and inputs the result of the first completed stage into the function.
<U> CompletableFuture<U>applyToEither(CompletionStage<? extends T> other, Function<? super T,U> fn)
Generates a new `CompletionStage` set to execute a predetermined function once either the current or another specified stage finishes successfully, using the outcome of the first completed stage as the function's argument.
<U> CompletableFuture<U>applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn)
Creates a new `CompletionStage` that will execute a given function asynchronously, utilizing the default execution facility of this stage, once either the current stage or an alternative specified stage concludes successfully. The outcome of the first completed stage is used as the input for the function.
<U> CompletableFuture<U>applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T,U> fn, Executor executor)
Generates a fresh `CompletionStage`, which, upon normal finalization of either the current stage or a specified alternative, will carry out a provided function asynchronously using a designated executor. The function will receive the result of the first stage to complete successfully as its input.
booleancancel(boolean mayInterruptIfRunning)
Triggers the completion of this `CompletableFuture` with a `CancellationException` if it has not already been completed.
booleancomplete(T value)
Sets the return value for `get()` and similar methods to the specified value, provided this `CompletableFuture` has not yet been completed.
booleancompleteExceptionally(Throwable ex)
If the `CompletableFuture` hasn't been completed yet, it makes calls to `get()` and related methods throw the specified exception.
CompletableFuture<T>exceptionally(Function<Throwable,? extends T> fn)
Produces a new `CompletableFuture` that completes once the current `CompletableFuture` finishes. If the current future completes exceptionally, the new future completes with the result obtained by applying the provided function to the exception that caused the completion. Conversely, if the current `CompletableFuture` completes normally, the new one will also complete normally with the identical value.
Tget()
Blocks until this future is completed, and then retrieves its outcome.
Tget(long timeout, TimeUnit unit)
Pauses execution, up to a specified maximum duration, until this future completes, then returns its result if it becomes available within that timeframe.
TgetNow(T valueIfAbsent)
Delivers the result value or throws any encountered exception if the operation is complete; otherwise, it returns the specified valueIfAbsent.
intgetNumberOfDependents()
Provides an estimate of the number of `CompletableFutures` pending completion of this `CompletableFuture`.
<U> CompletableFuture<U>handle(BiFunction<? super T,Throwable,? extends U> fn)
Generates a new `CompletionStage` that executes a provided function with the result and any exception of this stage upon its completion, whether normal or exceptional.
<U> CompletableFuture<U>handleAsync(BiFunction<? super T,Throwable,? extends U> fn)
Creates a new `CompletionStage` set to execute a specified function asynchronously using this stage's default execution mechanism upon its completion, whether normal or exceptional. The function will receive this stage's outcome and any thrown exception as inputs.
<U> CompletableFuture<U>handleAsync(BiFunction<? super T,Throwable,? extends U> fn, Executor executor)
It produces a new `CompletionStage` that, upon the completion of this stage-be it normal or exceptional-executes a provided function using a designated executor. This function will be given this stage's result and any exception as arguments.
booleanisCancelled()
It indicates whether the `CompletableFuture` was cancelled prior to its normal completion by returning true.
booleanisCompletedExceptionally()
It returns true if the CompletableFuture concluded its execution because of an exception, indicating an error occurred during its operation.
booleanisDone()
It evaluates to true if the CompletableFuture concluded for any reason, including normal completion, encountering an exception, or being cancelled.
Tjoin()
The method retrieves the result value upon completion or throws an unchecked exception if the CompletableFuture concluded due to an exception.
voidobtrudeException(Throwable ex)
The operation ensures that any subsequent attempts to retrieve the result through the get() method or similar methods will result in the specified exception being thrown, irrespective of the CompletableFuture's current completion status.
voidobtrudeValue(T value)
The action forcefully updates the value that will be returned by the get() method and its related methods in the future, regardless of whether the CompletableFuture has already reached completion.
CompletableFuture<Void>runAfterBoth(CompletionStage<?> other, Runnable action)
It creates a new CompletionStage that triggers the specified action once both this stage and another provided stage have successfully completed.
CompletableFuture<Void>runAfterBothAsync(CompletionStage<?> other, Runnable action)
It creates a new CompletionStage that triggers the specified action through this stage's standard asynchronous execution service, upon the successful conclusion of both this stage and the specified additional stage.
CompletableFuture<Void>runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor)
It creates a new CompletionStage that executes an action with a specified executor after both this stage and another complete normally.
CompletableFuture<Void>runAfterEither(CompletionStage<?> other, Runnable action)
It creates a new CompletionStage to execute an action when either this stage or the specified other stage completes normally.
CompletableFuture<Void>runAfterEitherAsync(CompletionStage<?> other, Runnable action)
It initiates a new CompletionStage that, upon the normal completion of either this stage or another specified stage, performs the given action asynchronously using this stage's default execution mechanism.
CompletableFuture<Void>runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor)
Generates a new CompletionStage which executes a specified action with a provided executor once either this stage or the given other stage completes successfully.
static CompletableFuture<Void>runAsync(Runnable runnable)
Creates a new CompletableFuture that will be completed asynchronously by a task executing in the ForkJoinPool.commonPool(), following the execution of the specified action.
static CompletableFuture<Void>runAsync(Runnable runnable, Executor executor)
It generates a new CompletableFuture set to be completed asynchronously by a task operating within the specified executor, after the designated action has been performed.
static <U> CompletableFuture<U>supplyAsync(Supplier<U> supplier)
Creates a new CompletableFuture that will be asynchronously completed by a task in the ForkJoinPool.commonPool(), using the value produced from the given Supplier.
static <U> CompletableFuture<U>supplyAsync(Supplier<U> supplier, Executor executor)
Generates a new CompletableFuture that is completed asynchronously by a task executed within the specified executor, based on the value acquired from calling the provided Supplier.
CompletableFuture<Void>thenAccept(Consumer<? super T> action)
It creates a new CompletionStage which, upon the normal completion of this stage, will execute the provided action, passing the result of this stage as an argument to that action.
CompletableFuture<Void>thenAcceptAsync(Consumer<? super T> action)
It initiates a new CompletionStage that, following the normal completion of this stage, executes the given action asynchronously using this stage's default execution service, with the result of this stage supplied as the argument to the action.
CompletableFuture<Void>thenAcceptAsync(Consumer<? super T> action, Executor executor)
Generates a new CompletionStage which, upon normal completion of this stage, carries out the provided action using the specified Executor, taking the result of this stage as the input for the action.
<U> CompletableFuture<Void>thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action)
This creates a new CompletionStage that, upon the normal completion of both this stage and the specified other stage, executes the given action using the results of both stages as arguments.
<U> CompletableFuture<Void>thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action)
Initiates a new CompletionStage which, after both this stage and the given other stage complete successfully, executes the specified action asynchronously using this stage's default execution mechanism, with the outcomes of both stages serving as arguments to the action.
<U> CompletableFuture<Void>thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T,? super U> action, Executor executor)
Generates a new CompletionStage that, once both this stage and the specified other stage finish successfully, carries out the provided function using the designated executor, with the outcomes of both stages supplied as arguments to the function.
<U> CompletableFuture<U>thenApply(Function<? super T,? extends U> fn)
Creates a new CompletionStage which, upon the successful completion of this stage, executes the given function, passing the result of this stage as the function's argument.
<U> CompletableFuture<U>thenApplyAsync(Function<? super T,? extends U> fn)
Initiates a new CompletionStage that, following the normal conclusion of this stage, performs the specified function asynchronously using this stage's default execution service, with the stage's outcome as the input to the function.
<U> CompletableFuture<U>thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
Generates a new CompletionStage which, once this stage concludes successfully, will execute the provided function using the designated Executor, utilizing the result of this stage as the argument for the function.
<U,V> CompletableFuture<V>thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
Creates a new CompletionStage that, upon the normal completion of both this stage and the specified other stage, will run the given function, using the outcomes of both stages as the arguments.
<U,V> CompletableFuture<V>thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)
This initiates a new CompletionStage which, following the successful completion of both this stage and the specified other stage, executes the provided function asynchronously utilizing this stage's default execution service, with the results from both stages as the arguments to the function.
<U,V> CompletableFuture<V>thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor)
Generates a new CompletionStage that, after both this stage and the designated other stage finish successfully, carries out the specified function using the chosen executor, incorporating the results of both stages as arguments for the function.
<U> CompletableFuture<U>thenCompose(Function<? super T,? extends CompletionStage<U>> fn)
This creates a new CompletionStage that, upon the normal completion of this stage, executes the given function, passing this stage itself as the argument to that function.
<U> CompletableFuture<U>thenComposeAsync(Function<? super T,? extends CompletionStage<U>> fn)
Initiates a new CompletionStage which, after the successful completion of this stage, performs the specified function asynchronously using this stage's default execution mechanism, with this stage itself provided as the argument to the function.
<U> CompletableFuture<U>thenComposeAsync(Function<? super T,? extends CompletionStage<U>> fn, Executor executor)
Generates a new CompletionStage that, once this stage concludes successfully, will execute the provided function using the designated Executor, with the result of this stage serving as the argument for the function.
CompletableFuture<Void>thenRun(Runnable action)
Creates a new CompletionStage that will execute the specified action once this stage completes successfully.
CompletableFuture<Void>thenRunAsync(Runnable action)
This initiates a new CompletionStage which, following the successful completion of this stage, performs the given action asynchronously utilizing this stage's default execution service.
CompletableFuture<Void>thenRunAsync(Runnable action, Executor executor)
Generates a new CompletionStage that, upon the normal completion of this stage, carries out the specified action using the chosen Executor.
CompletableFuture<T>toCompletableFuture()
The statement simply returns the current instance of the CompletableFuture.
StringtoString()
This returns a string that identifies this CompletableFuture and describes its state of completion.
CompletableFuture<T>whenComplete(BiConsumer<? super T,? super Throwable> action)
Creates a new CompletionStage that, upon completion of this stage, executes the specified action and carries the same outcome or exception as this stage.
CompletableFuture<T>whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
This initiates a new CompletionStage that, once this stage completes, performs the given action asynchronously using this stage's default execution service, mirroring the result or exception of this stage.
CompletableFuture<T>whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
Generates a new CompletionStage that, following the completion of this stage, carries out the specified action using the designated Executor, and maintains the same outcome or exception as this stage.

Exception Handling of CompletableFuture

Consider the following figure that represents the five CFs:

CompletableFuture in Java

Suppose Five CFs in execution and CF21 raises an exception then all the depending CF (CF31 and CF41) are in error. It means that:

  • The call to isCompletedExceptionally() method returns true.
  • The call to get() throws an ExecutionException which causes the root Exception.

Consider the following figure, in which we have created CF30 with an exception.

CompletableFuture in Java

When CF21 executes normally, then CF30 just transmits the value. If it raises an exception, CF30 handles it and generate value for CF31.

There are three method to handle an exception:


Next TopicJava Tutorial