第一章:Java结构化并发结果获取概述
在现代Java应用开发中,随着异步任务数量的增加,传统线程管理方式逐渐暴露出复杂性和可维护性差的问题。Java 19引入的结构化并发模型旨在通过将并发任务组织为层次结构,提升代码的可读性与错误传播能力,尤其在结果获取方面提供了统一且安全的机制。
结构化并发的核心理念
- 将多个异步任务视为一个整体,确保所有子任务完成前主线程不会提前退出
- 异常能够被正确捕获并向上抛出,避免静默失败
- 支持以同步方式获取异步执行结果,简化编程模型
使用StructuredTaskScope获取结果
通过
StructuredTaskScope可以定义一组并发任务,并等待它们完成或超时。以下示例展示了如何并发获取两个远程服务的结果:
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future user = scope.fork(() -> fetchUser()); // 子任务1
Future order = scope.fork(() -> fetchOrder()); // 子任务2
scope.join(); // 等待所有任务完成
scope.throwIfFailed(); // 若任一任务失败则抛出异常
String userName = user.resultNow(); // 获取结果
int orderId = order.resultNow();
System.out.println("用户: " + userName + ", 订单数: " + orderId);
}
上述代码中,
resultNow()方法用于在确认任务成功后立即提取结果,若任务尚未完成或发生异常,则会抛出相应异常。
关键优势对比
| 特性 | 传统Futures | 结构化并发 |
|---|
| 生命周期管理 | 手动管理 | 自动作用域管理 |
| 异常处理 | 需逐个检查 | 统一聚合处理 |
| 结果获取方式 | get() 阻塞调用 | resultNow() 安全提取 |
graph TD
A[主任务] --> B[子任务1]
A --> C[子任务2]
B --> D[获取结果1]
C --> E[获取结果2]
D --> F[合并结果]
E --> F
F --> G[返回最终结果]
第二章:CompletableFuture核心机制与实践
2.1 CompletableFuture的基本创建与完成
创建CompletableFuture实例
CompletableFuture提供了多种静态方法用于创建异步任务。最基础的是CompletableFuture.supplyAsync(),它接受一个Supplier函数式接口,在默认的ForkJoinPool线程池中执行异步计算。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try { Thread.sleep(1000); } catch (InterruptedException e) { }
return "Hello from async";
});
上述代码创建了一个异步任务,返回字符串结果。supplyAsync适用于有返回值的场景;若无需返回值,可使用runAsync(),它接收Runnable接口。
手动完成与异常处理
可通过complete()方法手动设置结果,使Future立即完成:
future.complete("Success"):设置正常结果future.completeExceptionally(new RuntimeException()):强制以异常结束
这在超时控制或条件提前终止时非常有用。
2.2 链式调用与结果转换:thenApply与thenCompose
在 CompletableFuture 中,
thenApply 和
thenCompose 是实现异步任务链式编排的核心方法,二者均支持对前一阶段结果进行处理,但语义不同。
thenApply:同步转换结果
thenApply 接受一个 Function,将上一阶段的完成结果进行同步转换,返回新的值并封装为 CompletableFuture。
CompletableFuture<String> future =
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World");
上述代码中,字符串 "Hello" 被映射为 "Hello World",thenApply 适用于非异步的纯函数转换。
thenCompose:扁平化异步调用
当转换逻辑本身返回 CompletableFuture 时,应使用 thenCompose 避免嵌套层级加深。
CompletableFuture<String> future2 =
CompletableFuture.supplyAsync(() -> "Hello")
.thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " Async"));
该方法等价于 monadic flatMap,将异步操作串联成线性流程,避免 CompletableFuture<CompletableFuture<T>> 结构。
2.3 并行组合多个异步任务:allOf与anyOf
在处理多个异步操作时,
CompletableFuture 提供了
allOf 和
anyOf 方法来组合任务,实现更高效的并发控制。
allOf:等待所有任务完成
CompletableFuture all = CompletableFuture.allOf(
CompletableFuture.runAsync(() -> System.out.println("Task 1")),
CompletableFuture.runAsync(() -> System.out.println("Task 2"))
);
all.join(); // 阻塞直至所有任务完成
allOf 接收多个
CompletableFuture 实例,返回一个
Void 类型的 future,仅当所有子任务都完成后才触发后续操作。
anyOf:任一任务完成即响应
CompletableFuture