Middle
What is CompletableFuture?
sobes.tech AI
Answer from AI
CompletableFuture in Java 8+ is an extension of the Future model, adding capabilities for asynchronous programming and task composition.
It implements the CompletionStage and Future interfaces. CompletionStage defines a contract for asynchronous execution and composition of computation steps.
Key features:
- Non-blocking operations: Allows tasks to be executed asynchronously without blocking the main thread.
- Composition: Provides a rich API for chaining and combining results of multiple asynchronous operations.
- Exception handling: Built-in mechanisms for error handling in asynchronous streams.
- Creation: Can create completed, incomplete, or exceptionally completed
CompletableFuture. - Dependencies: Enables creating chains of dependent tasks, where the execution of one depends on the completion of another.
- Parallel execution: Methods like
allOfandanyOffor executing multiple tasks in parallel.
Examples of usage:
-
Creating and completing:
// Creating a completed CompletableFuture CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Hello"); // Creating an incomplete CompletableFuture and completing it later CompletableFuture<String> future = new CompletableFuture<>(); // ... perform asynchronous work ... future.complete("Done"); // Or with an error // future.completeExceptionally(new RuntimeException("Error")); -
Performing an asynchronous task:
CompletableFuture<String> asyncFuture = CompletableFuture.supplyAsync(() -> { // Asynchronous work (e.g., reading from a file, network request) try { Thread.sleep(1000); } catch (InterruptedException e) { throw new IllegalStateException(e); } return "Async Result"; }); -
Chaining with
thenApply:CompletableFuture<Integer> result = CompletableFuture.supplyAsync(() -> 10) .thenApply(x -> x * 2); // The result of the previous step is passed to the function -
Combining with
thenCombine:CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10); CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20); CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (res1, res2) -> res1 + res2); // Combining results of two CompletableFutures -
Handling completion with
thenAccept:CompletableFuture.supplyAsync(() -> "Final result") .thenAccept(result -> System.out.println("Task finished with result: " + result)); // Performing an action after completion without returning a value -
Handling exceptions with
exceptionally:CompletableFuture<String> futureWithException = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Something went wrong"); }).exceptionally(ex -> { System.err.println("Error occurred: " + ex.getMessage()); return "Default Value"; // Returning a default value in case of error });
CompletableFuture greatly simplifies writing asynchronous and non-blocking code in Java, making it more readable and maintainable compared to traditional callbacks or blocking calls like Future.get().