组合式异步编程
使用场景
有一定依赖关系的异步任务。
简单介绍
CompletableFuture,它是一个具体的类,实现了两个接口,一个是Future,另一个是CompletionStage。
Future表示异步任务的结果,而CompletionStage的字面意思是完成阶段。
多个CompletionStage可以以流水线的方式组合起来,对于其中一个CompletionStage,它有一个计算任务,但可能需要等待其他一个或多个阶段完成才能开始,它完成后,可能会触发其他阶段开始运行。
CompletionStage提供了大量方法,使用它们,可以方便地响应任务事件,构建任务流水线,实现组合式异步编程。
使用Future,我们只能通过get获取结果,而get可能会需要阻塞等待,而通过CompletionStage,可以注册回调函数,当任务完成或异常结束时自动触发执行。
Future/FutureTask使用Runnable或Callable表示任务,其中Runnable没有返回值,Callable有返回值。
CompletableFuture则使用Runnable和Supplier表示任务,其中Supplier代替了Callable表示有返回值,与Callable的区别是,它不能抛出受检异常,如果会发生异常,可以抛出运行时异常。
CompletableFuture是对Future的增强,但可以响应结果或异常事件,有很多方法构建异步任务流。
使用CompletableFuture,可以简洁自然地表达多个异步任务之间的依赖关系和执行流程,大大简化代码,提高可读性。
基本使用
CompletableFuture有Future的所有函数功能,除此之外还有如下一些功能:
函数 | 使用说明 |
supplyAsync | 它接受两个参数supplier和executor,使用executor执行supplier表示的任务,返回一个CompletableFuture,调用后,任务被异步执行,这个方法立即返回。 |
runAsync | 与上面类似,只是无需返回结果,即参数中的supplier换成了runnable。 |
join | 等待任务结束,但它不会抛出受检异常。如果任务异常结束了,join会将异常包装为运行时异常CompletionException抛出。 |
getNow | 与join类似,区别是,如果任务还没有结束,getNow不会等待,而是会返回传入的参数valueIfAbsent。 |
isCompletedExceptionally | 判断任务是否是异常结束。 |
complete | 在CompletableFuture中设置任务成功完成。 |
completeExceptionally | 在CompletableFuture中设置任务异常结束,且附上具体异常。 |
whenComplete |
|
handle | 同whenComplete类似,区别是handle回调函数是一个BiFunction,也是接受两个参数,一个是正常结果,另一个是异常,但BiFunction有返回值,在handle返回的CompletableFuture中,结果会被BiFunction的返回值替代,即使原来有异常,也会被覆盖。 |
exceptionally |
|
任务流
使用CompletableFuture,可以方便地构建有多种依赖关系的任务流。
thenRun |
|
thenAccept/thenApply |
|
thenCompose | 与thenApply类似,不同的是这个转换函数fn的返回值类型是CompletionStage,也就是说,它的返回值也是一个阶段。thenCompose与thenApply的区别就如同Stream API中flatMap与map的区别。 |
runAfterBoth thenCombine thenAcceptBoth |
|
runAfterEither applyToEither acceptEither | 上面三个函数要求两个阶段都完成后才执行下一个任务,如果只需要其中任意一个阶段完成,可以使用这三个方法。 |
allOf |
|
anyOf |
|
CompletableFuture中有很多名称带有run、accept或apply的方法,它们一般与任务的类型相对应:
- run -> Runnable
- accept -> Consumer
- apply -> Function
根据任务由谁执行,一般有三类对应方法:
- 名称不带Async的方法由当前线程或前一个阶段的线程执行
- 带Async但没有指定Executor的方法由默认Excecutor(Fork-JoinPool.commonPool()或ThreadPerTaskExecutor)执行
- 带Async且指定Executor参数的方法由指定的Executor执行
知其然知其所以然,只有掌握了底层原理,借助第一性原理,才可以在日常开发和项目中运用自如,潇洒走江湖。 专为27届毕业生准备,托起您的就业梦。 该专辑会不定时更新,建议27届同学订阅,入职后扎实的基本功可以帮您争取更好的机会和项目。
查看15道真题和解析