CompletableFuture 源码解析
时间: 2023-05-15 20:06:53 浏览: 152
CompletableFuture 是 Java 8 中新增的一个类,它提供了一种异步编程的方式,可以让我们更加方便地处理异步任务。CompletableFuture 的源码实现主要是基于 Java 的 Future 和 CompletionStage 接口,它提供了一系列的方法来处理异步任务的执行和结果的处理。其中,最常用的方法包括 thenApply、thenAccept、thenRun、thenCompose、thenCombine 等。这些方法可以让我们在异步任务执行完成后,对其结果进行处理,或者将多个异步任务组合起来执行。如果你想深入了解 CompletableFuture 的源码实现,可以参考 Java 8 的官方文档或者相关的开源实现。
相关问题
completablefuture whenComplete 源码
`CompletableFuture<T>` 是 Java 8 引入的一个类,用于异步编程模型。它提供了一种强大的机制来处理复杂的异步操作链,并允许开发者编写非阻塞、回调驱动风格的代码。
### `whenComplete` 方法
`whenComplete` 是 CompletableFuture 提供的一种方法,它接受一个 BiConsumer 类型的函数式接口作为参数。这个函数会在当前阶段完成之后被触发执行,无论结果是正常结束还是抛出异常。该函数会接收两个输入参数:
1. 当前 completable future 的返回值;
2. 如果有异常,则为对应的 Throwable 对象;如果没有发生异常则为 null.
下面是 `whenComplete` 方法的部分源码解析:
```java
public CompletableFuture<Void> whenComplete(BiConsumer<? super T, ? super Throwable> action) {
return uniWhenCompleteStage(null, action);
}
private <U> CompletableFuture<U> uniWhenCompleteStage(CompletionStage<? extends U> cs,
BiFunction<?, ?, ?> fn) {
if (fn == null) throw new NullPointerException();
// 创建一个新的 AsyncRun 结构体表示此阶段的任务.
CompletableFuture<U> d = new CompletableFuture<>();
// 添加依赖关系并尝试将新任务注册到前面所有节点上,
// 确保当它们完成后能够继续向下传播直至到达最终消费者处。
UniWhenComplete<T, U> c;
withDependents(() -> {
c = new UniWhenComplete<>(d, this, castNonNull(fn));
push(c); // 把UniWhenComplete实例压入队列中等待执行
});
tryReleaseOtherNull();
// 若已有可用的结果,则立即运行给定的动作
if ((c != null && !unipush(this, c)) || isDone())
releaseOther(d);
return d;
}
```
从上面简化的源代码可以看出,在调用 `whenComplete` 后实际上创建了一个新的 `CompletableFuture` 实例 (`d`) 并关联了旧的 CompletableFutures 和指定的操作(`action`). 这样可以保证只有当原始 Future 完成时才会触发后续动作,并且整个过程是非阻塞式的。
### 使用示例
下面是一个简单的例子展示了如何使用 `whenComplete()` 来处理成功和失败的情况。
```java
import java.util.concurrent.CompletableFuture;
public class Example {
public static void main(String[] args){
CompletableFuture<String> cf =
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + ", World!")
.whenComplete((result, ex) -> {
if(ex == null)
System.out.println("Result was: "+ result );
else{
System.err.println("Exception occurred: " +ex.getMessage());
}
})
.exceptionally(thr-> {System.err.println(thr.toString());return null;});
// 主线程休眠一段时间以便于观察输出信息
sleepSecond(5);
}
private static void sleepSecond(int seconds) {
try {
Thread.sleep(seconds * 1000L);
} catch (InterruptedException e) {}
}
}
```
在这个例子中我们构建了一个包含供应者 Supplier 和映射器 Function 的异步流水线,然后附加了 `whenComplete`,不管是否有异常都会打印相关信息出来。
阅读全文
相关推荐
















