浅析 Java8 引入的 CompletableFuture
本文最后更新于 2025年8月17日 21:42
对于 Java 程序来说,Java 8 中引入的 CompletableFuture
可以帮助我们来做多个任务的编排,功能非常强大。
Future
Future
类是异步思想的典型运用。我们可以将一个耗时的任务交给子线程去执行,等到执行完毕后我们可以直接通过 Future
类获取结果,这样一来便可显著提高工作效率。在 Java 中,Future
类只是一个泛型接口,位于 java.util.concurrent
包下,其中定义了 5 个方法:
1 |
|
CompletableFuture
Future
在实际使用过程中存在一些局限性,比如不支持异步任务的编排组合、获取计算结果的 get()
方法为阻塞调用。Java 8 引入CompletableFuture
类可以解决Future
的这些缺陷。CompletableFuture
除了提供了更为好用和强大的 Future
特性之外,还提供了函数式编程、异步任务编排组合等能力。CompletableFuture
还同时实现了 Future
和 CompletionStage
接口。
CompletableFuture 的使用
想要使用,首先我们应该创建一个 CompletableFuture
,我们可以通过 new
关键字或者静态工厂方法来创建。
1 |
|
当我们将任务提交了以后,就要考虑如何处理返回的结果,比较常用的方法有以下几个:
- thenApply() ,对上一步的结果做转换,有返回值。
1 |
|
- thenAccept(),消费上一步的结果,无返回值。
1 |
|
- thenRun(),不关心上一步的结果,只在前一步完成后再执行一个动作(无参、无返回值)。
1 |
|
- whenComplete(),无论正常还是异常,都会在任务结束时回调,可以拿到结果和异常。
1 |
|
CompletableFuture 存在哪些问题
使用 CompletableFuture
可以通过并行的方式加快接口的响应速度,但是这会给我们带来什么问题呢?
- 线程池资源消耗:由于传入的任务是通过子线程去执行的,所以会有额外的资源消耗。
- 异常处理复杂:链式调用时,一旦某个环节抛异常,后续计算可能直接中断,所以要显式捕获异常进行兜底。
- 上下文传递:比如 ThreadLocal 中的变量,日志的 TraceID都无法传递到子线程当中。
- 内存和 GC 压力较大:需要维护一堆回调和状态,链式调用过多可能导致内存占用增加,GC 压力变大。
浅析 Java8 引入的 CompletableFuture
http://example.com/2025/08/16/浅析 Java8 引入的 CompletableFuture/