CompletionStage 接口详解
Java CompletionStage 接口详解
CompletionStage 是 Java 并发编程中用于表示异步计算阶段的接口,通常与 CompletableFuture 结合使用。它允许定义多个依赖阶段,当前一阶段完成时触发后续操作,支持链式异步任务编排。
1. 调用示例
CompletableFuture 是 CompletableFuture 的实现,如下代码是 CompletableFuture 方法的典型调用示例。
示例代码
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10);
future
.thenApplyAsync(x -> x * 2) // 异步转换:20
.thenCombine(CompletableFuture.supplyAsync(() -> 5), (a, b) -> a + b) // 合并结果:25
.thenAccept(result -> System.out.println("Result: " + result)) // 消费结果
.exceptionally(ex -> {
System.err.println("Error: " + ex.getMessage());
return null;
});
示例代码的流程图
sequenceDiagram
participant A as supplyAsync(10)
participant B as thenApplyAsync(x*2)
participant C as supplyAsync(5)
participant D as thenCombine(a+b)
participant E as thenAccept(print)
participant F as exceptionally
A->>B: 触发异步计算 (10 → 20)
par 并行执行
B-->>D: 结果20
C-->>D: 结果5
end
D->>E: 合并结果25
E->>E: 若无异常,结束
Note over E,F: 若异常,跳转至 exceptionally 处理
2. 核心原理
CompletionStage 阶段的处理逻辑可通过如下形式定义:
- Function:接收输入并返回结果,对应方法如
thenApply()。stage.thenApply(x -> x * 2); // 对结果进行计算 - Consumer:接收输入但不返回结果,对应方法如
thenAccept()。stage.thenAccept(x -> System.out.println(x)); // 消费结果 - Runnable:不接收输入也不返回结果,对应方法如
thenRun()。stage.thenRun(() -> System.out.println("Done")); // 执行操作 - Compose:通过
thenCompose()将阶段的结果转换为另一个阶段,避免嵌套。stage.thenCompose(x -> createNewStage(x)); // 将结果展平为新阶段
阶段处理方法的表格对比
| 方法类型 | 功能描述 | 输入参数 | 返回值 | 示例方法 |
|---|---|---|---|---|
| 转换(Function) | 处理结果并返回新值 | T → R | R | thenApply(), thenCompose() |
| 消费(Consumer) | 处理结果但不返回 | T → void | void | thenAccept() |
| 动作(Runnable) | 无输入无输出的操作 | void | void | thenRun() |
| 合并(Compose) | 合并两个阶段的结果 | T,U → V | V | thenCombine() |
| 异常处理 | 处理正常/异常结果 | (T, Throwable) | - | whenComplete(), handle() |
CompletionStage 核心流程示意图
flowchart LR
subgraph 触发条件
A[Stage1: 完成] -->|thenApply| B[Stage2: Function]
A -->|thenAccept| C[Stage3: Consumer]
A -->|thenRun| D[Stage4: Runnable]
E[Stage5] & F[Stage6] -->|thenCombine| G[合并结果]
E -->|applyToEither| H[取最先完成的结果]
end
subgraph 执行方式
B -->|默认执行| B_Sync[同步: 触发线程]
B -->|Async后缀| B_Async[异步: ForkJoinPool]
B -->|自定义Executor| B_Custom[指定线程池]
end
subgraph 异常处理
B -->|正常完成| B_Normal[传递结果]
B -->|异常完成| B_Error[传播异常]
B_Error -->|whenComplete| I[记录异常]
B_Error -->|handle| J[返回替代结果]
end
classDef stage fill:#f9f,stroke:#333;
classDef async fill:#6f9,stroke:#333;
classDef error fill:#f96,stroke:#333;
class A,B,C,D,E,F,G,H,I,J stage
class B_Async,B_Custom async
class B_Error,I,J error
3. 触发条件
阶段的触发方式取决于前置阶段的完成情况:
- 单个阶段完成:使用
then前缀方法,如thenApply()。 - 两个阶段均完成:合并结果,如
thenCombine()。stage1.thenCombine(stage2, (x, y) -> x + y); // 合并两个结果 - 任一阶段完成:使用
applyToEither()等方法,结果不确定。stage1.applyToEither(stage2, x -> x); // 取最先完成的结果
4. 执行方式
支持三种执行模式:
- 默认执行:由触发阶段的线程同步执行。
- 异步执行:通过
async后缀方法(如thenApplyAsync())提交到默认线程池(如ForkJoinPool)。 - 自定义执行器:显式指定
Executor,控制线程管理。stage.thenApplyAsync(x -> x * 2, customExecutor); // 使用自定义线程池
5. 异常处理
CompletionStage 的异常处理像一个「管道中的错误传递」——如果不主动处理,异常会一直传递到链的末端;而通过 handle/exceptionally 可以像「阀门」一样截断异常,替换为正常值继续流动。
- whenComplete():无论正常或异常完成,均执行操作,但保留原结果。
stage.whenComplete((result, ex) -> { if (ex != null) System.out.println("Error: " + ex); }); - handle():可处理异常并返回替代结果,影响后续阶段。
stage.handle((result, ex) -> ex != null ? 0 : result); // 异常时返回默认值 - 异常传播:若阶段抛出异常,所有依赖它的阶段将以
CompletionException包装异常完成。依赖多个阶段时,异常来源可能不确定。
异常处理方法表格对比
| 方法 | 作用 | 是否改变结果 | 示例 |
|---|---|---|---|
| whenComplete | 记录日志,但保留原结果/异常 | ❌ 不改变 | stage.whenComplete((res, ex) -> log(ex)) |
| handle | 处理异常并返回替代结果 | ✔️ 改变 | stage.handle((res, ex) -> ex != null ? 0 : res) |
| exceptionally | 仅处理异常,返回默认值 | ✔️ 改变 | stage.exceptionally(ex -> 0) |
6. 注意事项
- 参数限制:除结果参数可为
null外,其他参数非空,否则抛出NullPointerException。 - 顺序不保证:依赖关系仅控制触发时机,不保证执行顺序。
- 实现扩展:接口本身不提供创建或强制完成方法,需通过实现类(如
CompletableFuture)实现。
示例:链式调用与异常处理
CompletableFuture.supplyAsync(() -> fetchData())
.thenApply(data -> process(data))
.exceptionally(ex -> handleError(ex))
.thenAccept(result -> save(result));
此链式调用中,supplyAsync 异步获取数据,thenApply 处理结果,exceptionally 处理异常并返回默认值,最后 thenAccept 保存结果。
总结
本文解释了 CompletionStage 的链式触发机制、异步执行策略及异常处理逻辑。其核心是通过函数式编程模型,将复杂的异步任务拆解为多个可组合的阶段,适合构建高并发、低延迟的应用。

浙公网安备 33010602011771号