Java CompletableFuture
In this page:
What is CompletableFuture?
CompletableFuture, introduced in Java 8, supports asynchronous, non-blocking programming by running tasks on a background thread and letting you attach callbacks that fire when the result is ready, instead of blocking the calling thread to wait for it.
Example: What is CompletableFuture?
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "done"); // runs in background
future.thenAccept(result -> System.out.println("Callback fired: " + result));
future.get(); // wait so main() doesn't exit before the callback runs
}
}
Login to try C/C++/Java/PHP code in the editor
Running Tasks with runAsync()
The static runAsync() method executes a task asynchronously on a background thread pool. It accepts a Runnable and returns no result, which makes it the right choice for fire-and-forget side effects like logging or sending a notification.
Example: Running Tasks with runAsync()
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("Fire-and-forget task")); // no result
future.get();
}
}
Login to try C/C++/Java/PHP code in the editor
SupplyAsync and Callbacks
supplyAsync() runs a task that produces a result asynchronously, and chaining its output to thenAccept() lets you process that completed value once it's ready, all without blocking the calling thread at any point in the chain.
Example: SupplyAsync and Callbacks
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture.supplyAsync(() -> 10 * 5)
.thenAccept(result -> System.out.println("Result: " + result))
.get(); // never blocks until this final wait
}
}
Login to try C/C++/Java/PHP code in the editor
Combining Futures
thenCombine() lets you combine two independent CompletableFutures and process both of their results together as soon as they've both finished, which is useful when two unrelated async operations (like two separate API calls) both need to complete before you can proceed.
Example: Combining Futures
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<Integer> a = CompletableFuture.supplyAsync(() -> 5);
CompletableFuture<Integer> b = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> combined = a.thenCombine(b, (x, y) -> x + y);
System.out.println(combined.get());
}
}
Login to try C/C++/Java/PHP code in the editor
Exception Handling
exceptionally() lets you catch and handle errors thrown anywhere inside a chain of async background tasks, letting you supply a safe fallback value instead of the exception propagating uncaught and silently failing the whole async pipeline.
Example: Exception Handling
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) throws Exception {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("task failed");
}).exceptionally(ex -> -1); // safe fallback instead of propagating uncaught
System.out.println(future.get());
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 19 topics to unlock
0/19 topics done
Complete these topics first:
- Java Reflection API
- Java Annotations Advanced
- Java Garbage Collection
- Java Memory Management
- Java Performance Optimization
- Java Advanced Interview Questions
- Java CompletableFuture
- Java Atomic Classes
- Java Locks & Semaphores
- Java Concurrent Collections
- Java Cryptography Basics
- Java Hashing (MD5, SHA)
- Java SSL & HTTPS
- Java Logging (Log4j/SLF4J)
- Java Serialization Advanced
- Java Interview Questions Advanced
- Java Connection Pooling
- Java Test Driven Development
- Java Integration Testing