In Java, a Future is a representation of a task that may or may not be completed. It is used to retrieve the result of an asynchronous computation. A Future can be created by calling the submit method on an ExecutorService. The result of the computation can be obtained by calling the get method on the Future object. The get method is a blocking call and will wait until the computation is complete.
A CompletableFuture is a type of Future that provides more advanced features. It represents a promise that a computation will be completed in the future. It can be used to chain together a series of asynchronous operations. A CompletableFuture can be created by calling the CompletableFuture constructor, or by calling the supplyAsync or runAsync methods on an ExecutorService.
Here are some key differences between a Future and a CompletableFuture in Java:
Completion: A Future only represents the result of a computation, whereas a CompletableFuture represents both the result and the completion of a computation. This means that a CompletableFuture can be completed manually, whereas a Future cannot.
Chaining: A CompletableFuture can be chained together with other CompletableFutures to create a pipeline of asynchronous operations. This is not possible with a Future.
Exception Handling: A CompletableFuture provides more advanced exception handling capabilities than a Future. It has methods like exceptionally and handle to handle exceptions in a more fine-grained way.
Here is an example code snippet that demonstrates the use of CompletableFuture:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) throws
ExecutionException, InterruptedException {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello, World!";
});
future.thenAccept(result -> System.out.println(result));
System.out.println("Waiting for future to complete...");
future.get();
}
}
In this example, a CompletableFuture is created using the supplyAsync method. The computation in the CompletableFuture is a simple sleep operation that returns the string "Hello, World!". The thenAccept method is called on the CompletableFuture to print the result of the computation when it is complete. The get method is called on the CompletableFuture to wait for the computation to complete. The output of this program will be:
Waiting for future to complete...
Hello, World!
Note that the message "Waiting for future to complete..." is printed before the result of the computation is printed. This demonstrates that the get method is a blocking call that waits for the computation to complete.