CompletableFuture in Java
Last Updated :
23 Jun, 2025
CompletableFuture provides a powerful and flexible way to write asynchronous, non-blocking code. It was introduced in Java 8 and has become popular due to its ease of use and ability to handle complex asynchronous workflows.
What is CompletableFuture?
CompletableFuture is a class in java.util.concurrent package that implements the Future and CompletionStage Interface. It represents a future result of an asynchronous computation. It can be thought of as a container that holds the result of an asynchronous operation that is being executed in a different thread. It provides a number of methods to perform various operations on the result of the async computation.
Creating a CompletableFuture
To create an instance of CompletableFuture, we can use the static method supplyAsync provided by CompletableFuture class which takes Supplier as an argument. Supplier is a Functional Interface that takes no value and returns a result.
Example:
Java
import java.util.concurrent.*;
class GFG {
public static void main(String[] args) throws Exception
{
CompletableFuture<String> greetingFuture
= CompletableFuture.supplyAsync(() -> {
// some async computation
return "Hello from CompletableFuture";
});
System.out.println(greetingFuture.get());
}
}
Output:
Hello from CompletableFuture
This creates a CompletableFuture that will execute the lambda function passed to supplyAsync in a separate thread. And after the execution, the result lambda function is returned by CompletableFuture Object
Composing CompletableFuture
One of the powerful features of CompletableFuture is its ability to compose multiple asynchronous operations. We can use methods like thenApply, thenCombine, thenCompose to perform operations on the result of one CompletableFuture and create a new CompletableFuture as a result.
Example:
Java
/*package whatever //do not write package name here */
import java.util.concurrent.*;
class GFG {
public static void main(String[] args) throws Exception
{
CompletableFuture<String> helloFuture
= CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> greetingFuture
= CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<String> combinedFuture
= helloFuture.thenCombine(
greetingFuture, (m1, m2) -> m1 + " " + m2);
System.out.println(combinedFuture.get());
}
}
Output:
Hello World
This creates two instances of CompletableFuture that return "hello" and "world". And using thenCombine, the result of both the CompletableFutures are concatenated and returned as a final result.
Handling Multiple CompletableFutures
Sometimes we need to run multiple independent CompletableFuture tasks in parallel and wait for all of them to complete, so in this case we can use methods like allOf and anyOf.
Example:
Java
import java.util.concurrent.*;
class GFG {
public static void main(String[] args) throws Exception {
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> 20);
// Running multiple tasks in parallel
CompletableFuture<Void> allOf = CompletableFuture.allOf(f1, f2);
// Waits for both futures to complete
allOf.join();
System.out.println("Future1 Result: " + f1.get());
System.out.println("Future2 Result: " + f2.get());
}
}
OutputFuture1 Result: 10
Future2 Result: 20
Note: The allOf() method is used to combine the results of multiple CompletableFuture instances.
Handling Exception in CompletableFuture
CompletableFuture provides methods like exceptionally and handle to handle exceptions and errors that might happen during asynchronous computation and provide a fallback value or perform some alternative operation.
Example:
Java
import java.util.concurrent.*;
class GFG {
public static void main(String[] args) throws Exception
{
CompletableFuture<Integer> resultFuture
// java.lang.ArithmeticException: / by zero
= CompletableFuture.supplyAsync(() -> 10 / 0)
.exceptionally(ex -> 0);
// 0 - returned by exceptionally block
System.out.println(resultFuture.get());
}
}
Output:
0
Inside supplyAsync, when 10 is divided by 0, It will throw ArithmeticException and control will go to exceptionally block and which in turn returns 0.
Similar Reads
Callable and Future in Java Prerequisite: Threads, Multi-threading The need for Callable There are two ways of creating threads â one by extending the Thread class and other by creating a thread with a Runnable. However, one feature lacking in  Runnable is that we cannot make a thread return result when it terminates, i.e. whe
6 min read
Java 8 Features - Complete Tutorial Java 8 is the most awaited release of the Java programming language development because, in the entire history of Java, it has never released that many major features. It consists of major features of Java. It is a new version of Java and was released by Oracle on 18 March 2014. Java provided suppor
9 min read
Hashtable in Java Hashtable class, introduced as part of the Java Collections framework, implements a hash table that maps keys to values. Any non-null object can be used as a key or as a value. To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method an
12 min read
Java Collectors Collectors is one of the utility class in JDK which contains a lot of utility functions. It is mostly used with Stream API as a final step. In this article, we will study different methods in the collector class. When it comes to the functional style of programming in Java, we typically have few fun
13 min read
HashTable compute() method in Java with Examples The compute(Key, BiFunction) method of Hashtable class allows to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping is found). If the remapping function passed in compute() of Hashtable returns null as a return value then the mapping is remov
3 min read
Hashtable get() Method in Java The Hashtable.get() method is a built-in method of the java.util.Hashtable class. This method is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the table contains no such mapping for the key. In this article, we will learn about the Ha
3 min read