CompletableFuture浅谈
一、Future 的局限性
- 获取结果只能阻塞式get(),线程阻塞,不能异步处理结果,也不能注册回调。
- 不支持链式调用,想要多个异步任务串联,需要手动管理多个 Future 对象,代码非常冗长
- 不支持组合多个异步任务,比如等待多个任务完成后再继续执行,或两个任务中任意一个完成就继续执行,需要手动写状态检查逻辑。
- 不支持异常处理链,如果一个异步任务中抛出异常,需要 try-catch 包裹,无法像函数式编程一样优雅地处理异常链。
二、CompletableFuture的API概述
1、异步任务创建。
supplyAsync(Supplier):创建带返回值的异步任务,默认使用ForkJoinPool线程池。
runAsync(Runnable):创建无返回值的异步任务,常用于执行副作用操作。
两种方法均可通过传入Executor参数指定自定义线程池。
2、结果处理与链式调用
thenApply(Function):对结果进行同步转换(如字符串拼接)。
thenAccept(Consumer):消费结果但不返回新值(如打印)。
thenRun(Runnable):结果无关的后置操作(如清理资源)。
以上方法均提供Async后缀版本(如thenApplyAsync),支持异步执行。
3、组合操作
thenCompose(Function):串联两个依赖的异步任务(前序结果作为后序输入)。
thenCombine(CompletableFuture, BiFunction):合并两个独立任务的结果。
applyToEither(CompletableFuture, BiFunction):当有一个任务正常完成时,就会进行下阶段任务
allOf(CompletableFuture…):等待所有任务完成。
anyOf(CompletableFuture…):等待任一任务完成。
4、异常处理。
exceptionally(Function):捕获异常并返回替代值。
handle(BiFunction):同时处理正常结果和异常。
5、获取CompletableFuture执行异步的返回
join():抛出抛出未经检查的异常CompletionException,不支持超时参数(推荐)
get():抛出经检查的异常InterruptedException和ExecutionException,需要在调用处捕获它们。支持超时参数
三、例子
1、supplyAsync
2、thenCompose
3、thenCombine
4、applyToEither
5、thenApply
6、exceptionally