标准答案
- 不指定 executor 时,部分异步阶段会使用公共线程池;阻塞 I/O 不应无边界占用公共池。
- 异常会沿阶段传播,exceptionally、handle 和 whenComplete 的语义不同,应明确是否恢复结果。
- orTimeout 影响 Future 的完成结果,不一定能强制终止已发出的底层 I/O;取消也需要下游支持。
- 多个 Future 组合时要设置整体 deadline,避免一个子任务无限等待。
题目解析
CompletableFuture 只是异步阶段的组合模型,线程池、队列、超时和下游连接仍需单独设计。阻塞数据库调用放进公共 ForkJoinPool,可能让无关异步任务一起排队。
exceptionally 通常把异常转换为恢复值,handle 同时接收结果和异常,whenComplete 更适合旁路记录;恢复为 null 之前要确认下游是否能区分“空结果”和“失败”。
orTimeout 和 cancel 主要改变 Future 的完成状态,不保证已经发出的底层 I/O 被强制终止。取消要传到 HTTP、数据库或任务执行器,并用幂等处理结果未知。
常见误区
- 误区:在公共 ForkJoinPool 中执行阻塞数据库调用。改正:使用有界、隔离的阻塞执行器,并限制连接和任务并发。
- 误区:异常阶段返回 null 让错误静默继续。改正:区分正常空值和失败,记录异常并定义降级语义。
- 误区:认为 cancel 一定能中止远端请求。改正:确认下游取消协议和连接关闭行为,无法取消时查询最终状态。