java9新特性-改进CompletableFuture

CompletableFuture 是 Java 8 中引入用于处理异步编程的核心类,它引入了一种基于 Future 的编程模型,允许我们以更加直观的方式执行异步操作,并处理它们的结果或异常
Java 9 对它做了一些增强,主要内容包括:

  • 新的工厂方法
  • 支持超时和延迟执行
  • 支持子类化

新的工厂方法

  • public static <U> CompletableFuture<U> completedFuture(U value)

此方法用于创建一个已经完成的 CompletableFuture 实例 ,允许我们快速创建一个已经有结果的 CompletableFuture,这对于单元测试或需要立即返回结果的场景非常有用

  • public static <U> CompletableFuture<U> failedFuture(Throwable ex)

此方法创建一个异常完成(异常终止)的 CompletableFuture 实例

方法接受的参数为 Throwable,表明为异常终止,它为异步编程提供了一种简洁的方式来表示已知的失败情况,这对于错误处理和异常测试场景非常重要

  • Java 9 引入了下面这对 stage-oriented 工厂方法,返回完成的或异常完成的 completion stages

CompletionStage completedStage(U value): 返回一个新的以指定 value 完成的CompletionStage ,并且只支持 CompletionStage 里的接口

CompletionStage failedStage(Throwable ex): 返回一个新的以指定异常完成的CompletionStage ,并且只支持 CompletionStage 里的接口

支持超时和延迟执行

在 Java 9 中,CompletableFuture 引入了支持超时和延迟执行的改进,这两个功能对于控制异步操作的时间行为至关重要

支持超时

  • public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)

允许为 CompletableFuture 设置一个超时时间。如果在指定的超时时间内未完成,CompletableFuture 将以 TimeoutException 完成

该方法为 CompletableFuture 提供了超时机制,这对于避免永久挂起的异步操作和保证响应性至关重要

@Test
public void orTimeTest() {
try {
CompletableFuture completableFuture = CompletableFuture.runAsync(()->{
System.out.println("异步任务开始执行....");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).orTimeout(2,TimeUnit.SECONDS);

completableFuture.join();
} catch (Exception e) {
System.out.println(e);
}
}
异步任务开始执行....
java.util.concurrent.CompletionException: java.util.concurrent.TimeoutException
  • public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

该允许在指定的超时时间内如果未完成,则用一个默认值来完成 CompletableFuture

value 为默认默认值。该方法提供了一种优雅的回退机制,确保即使在超时的情况下也能保持异步流的连续性和完整性

@Test
public void completeOnTimeoutTest() {
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(()->{
System.out.println("异步任务开始执行....");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "死磕 Java 新特性";
}).completeOnTimeout("死磕 Java",2,TimeUnit.SECONDS);

System.out.println("执行结果为:" + completableFuture.join());
}
异步任务开始执行....
执行结果为:死磕 Java

支持延迟执行

  • public static Executor delayedExecutor(long delay, TimeUnit unit, Executor executor)

CompletableFuture 提供了delayedExecutor() 来支持延迟执行,该方法创建一个延迟执行的 Executor,可以将任务的执行推迟到未来某个时间点

它能够让我们更加精确地控制异步任务的执行时机,特别是在需要根据时间安排任务执行的场景中

@Test
public void completeOnTimeoutTest() {
// 创建一个延迟执行的Executor
Executor delayedExecutor = CompletableFuture.delayedExecutor(3, TimeUnit.SECONDS);

// 使用延迟的Executor执行一个简单任务
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("任务延迟后执行...");
}, delayedExecutor);

// 等待异步任务完成
future.join();
}

支持子类化

在 Java 9 中,CompletableFuture 做了一些改进,使得 CompletableFuture 可以被更简单的继承

  1. newIncompleteFuture()

创建一个新的、不完整的 CompletableFuture 实例, 子类可以重写这个方法来返回 CompletableFuture 的子类实例,允许在整个 CompletableFuture API 中自定义实例的行为

  1. defaultExecutor()

该方法提供 CompletableFuture 操作的默认执行器,子类可以重写此方法以提供不同的默认执行器,这对于定制任务执行策略特别有用

  1. copy()

创建一个与当前 CompletableFuture 状态相同的新实例。子类可以重写此方法以确保复制的实例是特定子类的实例,而不仅仅是 CompletableFuture