1. Why choose CompleteFuture?
Traditional asynchronous programming usually relies on callbacks orFuture
, but these methods have some shortcomings:
- Callback hell: There are many nesting levels, and the code is difficult to read.
- Future's
get()
The method is blocking and cannot truly implement non-blocking programming.
CompletableFuture
The advantages are:
- Supports non-blocking operations.
- Provides rich APIs for task combination and processing.
- Better error handling mechanism.
2. Basic usage
Create a CompleteFuture
import ; public class CompletableFutureExample { public static void main(String[] args) { // Create an asynchronous task CompletableFuture<String> future = (() -> { try { (1000); // Simulation time-consuming operation } catch (InterruptedException e) { throw new RuntimeException(e); } return "Hello, CompletableFuture!"; }); // Get results non-blocking (result -> ("Result: " + result)); ("Main thread is not blocked"); // Prevent the main thread from exiting too early try { (2000); } catch (InterruptedException e) { (); } } }
Output
Main thread is not blocked Result: Hello, CompletableFuture!
3. Task combination
thenApply: Convert result
thenApply
Methods are used to convert the results of an asynchronous task to another type.
CompletableFuture<Integer> future = (() -> "42") .thenApply(Integer::parseInt) .thenApply(num -> num * 2); (result -> ("Final Result: " + result));
thenCompose: Chain call
thenCompose
Used to start another asynchronous task after one task is completed.
CompletableFuture<String> future = (() -> "Hello") .thenCompose(s -> (() -> s + " World!")); (::println);
thenCombine: Merge two tasks
thenCombine
The result of merging two independent asynchronous tasks.
CompletableFuture<String> future1 = (() -> "Hello"); CompletableFuture<String> future2 = (() -> "World"); CompletableFuture<String> result = (future2, (s1, s2) -> s1 + " " + s2); (::println);
4. Exception handling
In asynchronous tasks, exception handling is very important.CompletableFuture
Provides a variety of ways to handle exceptions gracefully.
Exceptionally: Catch exceptions and return default values
CompletableFuture<String> future = (() -> { if (true) { throw new RuntimeException("Something went wrong"); } return "Success"; }).exceptionally(ex -> { ("Exception: " + ()); return "Default Value"; }); (::println);
handle: Handle results and exceptions
handle
The method will be executed regardless of whether the task is successful or failed, and exception information can be accessed.
CompletableFuture<String> future = (() -> { if (true) { throw new RuntimeException("Error occurred"); } return "Success"; }).handle((result, ex) -> { if (ex != null) { ("Exception: " + ()); return "Recovered from error"; } return result; }); (::println);
5. Practical application scenarios
Concurrent request processing
When multiple requests need to be processed simultaneously, you can useallOf
oranyOf
method.
allOf: Wait for all tasks to complete
CompletableFuture<Void> allTasks = ( (() -> ("Task 1")), (() -> ("Task 2")), (() -> ("Task 3")) ); (() -> ("All tasks completed"));
anyOf: Return when any task is completed
CompletableFuture<Object> anyTask = ( (() -> "Task 1 completed"), (() -> "Task 2 completed") ); (result -> ("First completed: " + result));
6. Summary
CompletableFuture
It is a powerful tool for Java asynchronous programming, providing rich APIs to implement task creation, combination and exception handling. By proficiencyCompletableFuture
, can write more concise and efficient asynchronous code.
The above is the detailed content of Java using CompletableFuture to implement asynchronous programming. For more information about Java CompletableFuture asynchronous programming, please pay attention to my other related articles!