Future and CompletableFuture in Java
Introduction
Java provides multiple ways to perform asynchronous programming, and one of the key features introduced for this is the Future
and CompletableFuture
API. These classes help in executing long-running tasks in the background and improve performance by utilizing multi-threading.
In this article, we will explore Future
and CompletableFuture
in Java, their differences, advantages, and how they help in writing more efficient and non-blocking code.
What is Future
in Java?
Future<T>
is an interface introduced in Java 5 as part of the java.util.concurrent
package. It represents the result of an asynchronous computation and provides methods to check if the computation is complete, retrieve the result, or cancel the computation.
Key Methods in Future
Interface
-
get()
: Retrieves the result, blocking if necessary. -
get(long timeout, TimeUnit unit)
: Retrieves the result but waits only for a specified time. -
isDone()
: Checks if the task is completed. -
isCancelled()
: Checks if the task was canceled. -
cancel(boolean mayInterruptIfRunning)
: Cancels the task if possible.
Example of Future
in Java
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
Thread.sleep(2000);
return 10;
});
System.out.println("Doing something else while waiting...");
System.out.println("Result: " + future.get()); // Blocks until result is available
executor.shutdown();
}
}
Limitations of Future
-
Blocking Behavior: Calling
get()
blocks execution until the result is available. -
No Manual Completion: There is no way to manually complete a
Future
. -
No Chaining: Lacks support for chaining multiple asynchronous computations.
What is CompletableFuture
?
Java 8 introduced CompletableFuture<T>
in java.util.concurrent
, which extends Future
and overcomes its limitations. It provides powerful features for asynchronous programming, including chaining, combining multiple futures, and handling exceptions.
Key Features of CompletableFuture
-
Non-blocking Execution: Supports callbacks (
thenApply
,thenAccept
,thenRun
). -
Combining Multiple Tasks: Methods like
thenCombine
andallOf
allow multiple futures to work together. -
Exception Handling:
exceptionally
andhandle
help manage errors. -
Manual Completion:
complete()
allows manually completing a future.
Example of CompletableFuture
import java.util.concurrent.*;
public class CompletableFutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return 10;
});
future.thenApply(result -> result * 2)
.thenAccept(result -> System.out.println("Result: " + result));
Thread.sleep(3000); // Waiting for async execution
}
}
Chaining Futures
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(result -> result + " World")
.thenAccept(System.out::println);
Combining Multiple Futures
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> result = future1.thenCombine(future2, Integer::sum);
System.out.println("Sum: " + result.get());
Handling Exceptions
CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Error!"); })
.exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return 0;
})
.thenAccept(System.out::println);
Difference Between Future
and CompletableFuture
Feature | Future |
CompletableFuture |
---|---|---|
Blocking | Yes, get() blocks |
No, supports non-blocking callbacks |
Chaining | No | Yes, supports thenApply , thenCompose |
Exception Handling | No built-in support | Has exceptionally , handle |
Manual Completion | No | Yes, with complete() |
Combining Futures | No | Yes, with thenCombine , allOf |
Conclusion
Future
and CompletableFuture
are essential for asynchronous programming in Java. While Future
is useful, CompletableFuture
provides more flexibility, better exception handling, and non-blocking execution. For modern Java applications, CompletableFuture
is the recommended choice.
Sign up here with your email
ConversionConversion EmoticonEmoticon