1. 引言

Java 9 对 CompletableFuture 类进行了一些重要改进。这些改进作为 JEP 266 的一部分引入,主要解决了自 JDK 8 引入以来的常见问题和建议,特别是增加了对延迟和超时的支持、优化了子类化能力并新增了若干实用方法。

从代码层面看,API 新增了 8 个实例方法和 5 个静态方法。根据 Open JDK 的统计,为实现这些功能,大约修改了 2400 行代码中的 1500 行。

2. 实例 API 新增方法

实例 API 新增了 8 个方法:

  1. Executor defaultExecutor()
  2. CompletableFuture<U> newIncompleteFuture()
  3. CompletableFuture<T> copy()
  4. CompletionStage<T> minimalCompletionStage()
  5. CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
  6. CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)
  7. CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)
  8. CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

2.1 defaultExecutor() 方法

签名Executor defaultExecutor()

返回未指定 Executor 的异步方法所使用的默认执行器。

new CompletableFuture().defaultExecutor()

子类可以重写此方法,返回一个至少包含一个独立线程的执行器。

2.2 newIncompleteFuture() 方法

签名CompletableFuture<U> newIncompleteFuture()

newIncompleteFuture(又称"虚拟构造器")用于获取同类型的新 CompletableFuture 实例。

new CompletableFuture().newIncompleteFuture()

在子类化 CompletableFuture 时特别有用,因为它被几乎所有返回新 CompletionStage 的方法内部使用,允许子类控制这些方法返回的子类型。

2.3 copy() 方法

签名CompletableFuture<T> copy()

返回一个新的 CompletableFuture,其行为如下:

  • 当原实例正常完成时,新实例也正常完成
  • 当原实例因异常 X 异常完成时,新实例也以 CompletionException(X 作为原因)异常完成
new CompletableFuture().copy()

此方法可用于"防御性复制",防止客户端直接完成操作,同时仍能在特定 CompletableFuture 实例上安排依赖操作。

2.4 minimalCompletionStage() 方法

签名CompletionStage<T> minimalCompletionStage()

返回一个新的 CompletionStage,行为与 copy() 方法描述完全相同,但新实例在尝试获取或设置解析值时会抛出 UnsupportedOperationException

new CompletableFuture().minimalCompletionStage()

可通过 CompletionStage API 的 toCompletableFuture() 方法获取包含所有方法的完整 CompletableFuture

2.5 completeAsync() 方法

completeAsync 方法用于使用提供的 Supplier 给定的值异步完成 CompletableFuture

签名

CompletableFuture<T> completeAsync(Supplier<? extends T> supplier, Executor executor)
CompletableFuture<T> completeAsync(Supplier<? extends T> supplier)

两个重载方法的区别在于第二个参数(指定运行任务的 Executor)。未提供时将使用默认执行器(由 defaultExecutor() 返回)。

2.6 orTimeout() 方法

签名CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)

new CompletableFuture().orTimeout(1, TimeUnit.SECONDS)

若未在指定超时前完成,则以 TimeoutException 异常完成 CompletableFuture

2.7 completeOnTimeout() 方法

签名CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

new CompletableFuture().completeOnTimeout(value, 1, TimeUnit.SECONDS)

若未在指定超时前完成,则以给定值正常完成 CompletableFuture

3. 静态 API 新增方法

新增了几个实用方法:

  1. Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
  2. Executor delayedExecutor(long delay, TimeUnit unit)
  3. <U> CompletionStage<U> completedStage(U value)
  4. <U> CompletionStage<U> failedStage(Throwable ex)
  5. <U> CompletableFuture<U> failedFuture(Throwable ex)

3.1 delayedExecutor 方法

签名

Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)
Executor delayedExecutor(long delay, TimeUnit unit)

返回一个新的 Executor,在给定延迟后将任务提交给基础执行器(非正延迟则无延迟)。每次延迟从调用返回执行器的 execute 方法开始计算。未指定执行器时使用默认执行器(ForkJoinPool.commonPool())。

3.2 completedStagefailedStage 方法

签名

<U> CompletionStage<U> completedStage(U value)
<U> CompletionStage<U> failedStage(Throwable ex)

这些实用方法返回已解析的 CompletionStage 实例:completedStage 返回正常完成的实例,failedStage 返回以给定异常异常完成的实例。

3.3 failedFuture 方法

签名<U> CompletableFuture<U> failedFuture(Throwable ex)

failedFuture 方法新增了指定已异常完成的 CompletableFuture 实例的能力。

4. 实用场景示例

本节展示如何使用部分新 API。

4.1 延迟操作

此示例展示如何延迟 1 秒后用特定值完成 CompletableFuture。可通过 completeAsync 结合 delayedExecutor 实现:

CompletableFuture<Object> future = new CompletableFuture<>();
future.completeAsync(() -> input, CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS));

4.2 超时默认值

另一种实现延迟结果的方式是使用 completeOnTimeout。此示例定义一个 CompletableFuture,若 1 秒内未完成,则解析为给定输入值:

CompletableFuture<Object> future = new CompletableFuture<>();
future.completeOnTimeout(input, 1, TimeUnit.SECONDS);

4.3 超时异常

另一种可能是超时触发异常完成(以 TimeoutException)。例如,让 CompletableFuture 在 1 秒后超时(若之前未完成):

CompletableFuture<Object> future = new CompletableFuture<>();
future.orTimeout(1, TimeUnit.SECONDS);

5. 总结

Java 9 为 CompletableFuture API 带来了多项改进:

✅ 通过 newIncompleteFuture 虚拟构造器优化了子类化支持
✅ 新增了延迟和超时处理能力
✅ 实用方法遵循合理模式,简化了已解析实例的创建

这些改进使 CompletableFuture 在异步编程中更加灵活和健壮。本文示例代码可在 GitHub 仓库 中找到。