Sobes.tech
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 allOf and anyOf for executing multiple tasks in parallel.

Examples of usage:

  1. 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"));
    
  2. 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";
    });
    
  3. Chaining with thenApply:

    CompletableFuture<Integer> result = CompletableFuture.supplyAsync(() -> 10)
        .thenApply(x -> x * 2); // The result of the previous step is passed to the function
    
  4. 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
    
  5. 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
    
  6. 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().