CompletableFuture
是 Java 8 引入的一个强大的类,用于异步编程和处理并发任务。它是 Future
接口的增强版本,提供了更多的功能,允许更灵活地处理异步任务和非阻塞操作。
1. 基本概念
-
异步编程:
CompletableFuture
可以异步地执行任务,而不需要等待任务完成后才能执行后续操作。它允许你提交任务,并在任务完成时(无论是成功还是失败)处理结果。 -
非阻塞:与传统的
Future.get()
方法不同,CompletableFuture
提供了多种非阻塞方法来处理任务的结果,例如thenApply()
、thenAccept()
和thenRun()
,它们允许你在任务完成后自动执行操作,而不会主动阻塞主线程。
2. 创建 CompletableFuture
有多种方式来创建 CompletableFuture
,包括使用静态方法来创建异步任务。
示例 1:创建并立即完成的 CompletableFuture
CompletableFuture<String> future = CompletableFuture.completedFuture("Hello, World!"); System.out.println(future.get()); // 输出: Hello, World!
示例 2:异步执行任
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 模拟耗时任务 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Result from async task"; }); future.thenAccept(result -> System.out.println("Task completed with: " + result));
3. 链式操作
CompletableFuture
支持将多个任务串联在一起执行,允许你在一个任务完成后执行另一个任务。这通常通过方法链的方式实现,比如 thenApply()
或 thenCompose()
。
示例 3:链式执行任务
CompletableFuture.supplyAsync(() -> "Task 1 result") .thenApply(result -> { System.out.println("Processing: " + result); return result + " -> Task 2 result"; }) .thenAccept(finalResult -> System.out.println("Final result: " + finalResult));
4. 组合多个 CompletableFuture
你可以将多个异步任务组合在一起,并等待它们全部完成,或在第一个任务完成后执行操作。
示例 4:等待多个任务完成
java
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Task 1"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2"); CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2); combinedFuture.thenRun(() -> { System.out.println("All tasks are completed!"); });
示例 5:两个任务的结果组合
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Task 1"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2"); CompletableFuture<String> resultFuture = future1.thenCombine(future2, (result1, result2) -> { return result1 + " and " + result2; }); resultFuture.thenAccept(result -> System.out.println("Combined result: " + result));
5. 异常处理
CompletableFuture
提供了处理异常的机制,通过 exceptionally()
或 handle()
方法来捕获并处理异步任务中的异常。
示例 6:处理异常
复制代码
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { if (true) { throw new RuntimeException("Something went wrong!"); } return "Success"; }).exceptionally(ex -> { System.out.println("Caught exception: " + ex.getMessage()); return "Default result"; }); future.thenAccept(result -> System.out.println("Final result: " + result));
6. 常见方法
supplyAsync()
: 异步执行有返回值的任务。runAsync()
: 异步执行不返回值的任务。thenApply()
: 任务完成后对结果进行转换并返回一个新值。thenAccept()
: 任务完成后消费结果,不返回值。thenRun()
: 任务完成后执行另一个不依赖于结果的任务。thenCompose()
: 链式组合多个异步任务,结果依赖于前一个任务。allOf()
: 等待所有CompletableFuture
完成。anyOf()
: 任意一个CompletableFuture
完成后触发。exceptionally()
: 处理异常并返回默认值。handle()
: 同时处理正常结果和异常。
7. 总结
CompletableFuture
是 Java 处理异步任务和并发操作的重要工具。它比传统的 Future
更灵活,可以轻松实现非阻塞操作、任务链、并行执行以及异常处理。这使得它在现代异步编程中非常常用,尤其是在 I/O 密集型任务中(如文件下载、HTTP 请求)。