CompletableFuture 笔记

前言

  CompletableFuture继承于java.util.concurrent.Future,它本身具备Future的所有特性,并且基于JDK1.8的流式编程以及Lambda表达式等实现一元操作符、异步性以及事件驱动编程模型,可以用来实现多线程的串行关系,并行关系,聚合关系。它的灵活性和更强大的功能是Future无法比拟的。

一、创建方式

1. 用默认线程池

  CompletableFuture<String> future = new CompletableFuture<>();
  默认使用 ForkJoinPool.commonPool(),
        commonPool是一个会被很多任务 共享 的线程池,比如同一 JVM 上的所有 CompletableFuture、并行 Stream 都将共享 commonPool,commonPool 设计时的目标场景是运行 非阻塞的 CPU 密集型任务,为最大化利用 CPU,其线程数默认为 CPU 数量 - 1。

2. 用自定义线程池

ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 3,
      TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
      new ThreadPoolExecutor.DiscardOldestPolicy());
CompletableFuture.runAsync(() -> System.out.println("Hello World!"), pool);

二、使用示例

1. 构建异步任务

方法
有无返回值
描述
runAsync
无 (想想runnable    
进行数据处理,接收前一步骤传递的数据
supplyAsync
进行数据处理,接收前一步骤传递的数据,处理加工后返回。返回数据类型可以和前一步骤返回的数据类型不同

2. 单任务结果消费

方法
有无返回值
描述
thenApply
有,
以上阶段结果为入参
在前一个阶段上应用thenApply函数,将上一阶段完成的结果作为当前阶段的入参
thenAccept
无,
以上阶段结果为入参
消费前一阶段的结果
thenRun
无,
无入参
无返回值,并且无入参。
当上一阶段完成后,执行本阶段的任务
(1)thenApply
then意味着这个阶段的动作发生当前的阶段正常完成之后。本例中,当前节点完成,返回字符串message
Apply意味着返回的阶段将会对结果前一阶段的结果应用一个函数。
函数的执行会被阻塞
(2)thenAccept
(3)thenRun

3. 合并 结果消费 (and)

方法
有无返回值
描述
thenCombine
有返回值,入参为两个任务结果
一任务合并另外一个任务,两个任务都完成后,执行BiFunction,入参为两个任务结果,返回新结果
thenAcceptBoth
无返回值,入参为两个任务结果
(accept 有入参,但不返回)
一任务合并另外一个任务,两个任务都完成后,执行这个方法等待第一个阶段的完成(大写转换)。
 它的结果传给一个指定的返回CompletableFuture函数,它的结果就是返回的CompletableFuture的结果,入参为两个任务结果,不返回新结果
runAfterBoth
无返回值,无入参
合并另外一个任务,两个任务都完成后,执行Runnable,注意,这里的两个任务是同时执行
(1)thenCombine
  如果CompletableFuture依赖两个前面阶段的结果, 它复合两个阶段的结果再返回一个结果,我们就可以使用thenCombine()函数。整个流水线是同步的。

4. 任一 结果消费 (or)

方法
有无返回值
描述
applyToEither
有返回值,有入参
其中任一任务完成后,执行Function,结果转换,入参为已完成的任务结果。返回新结果,要求两个任务结果为同一类型
acceptEither
无返回值,有入参
其中任一任务完成后,执行Consumer,消费结果,入参为已完成的任务结果。不返回新结果,要求两个任务结果为同一类型
runAfterEither
无返回值,无入参
其中任一任务完成后,执行Runnable,消费结果,无入参。不返回新结果,不要求两个任务结果为同一类型
场景
  假设查询商品a,有两种方式,A和B,但是A和B的执行速度不一样,希望哪个先返回就用那个的返回值。

5. 级联任务

方法
有无返回值
描述
thenCompose
当原任务完成后,以其结果为参数,返回一个新的任务(而不是新结果,类似flatMap)
(1)thenCompose
  这个方法等待第一个阶段的完成(大写转换), 它的结果传给一个指定的返回CompletableFuture函数,它的结果就是返回的CompletableFuture的结果。
源码

6. 单任务结果 或 异常消费

方法
有无返回值
描述
handle
任务完成后执行BiFunction,结果转换,入参为结果或者异常,返回新结果
whenComplete
任务完成后执行BiConsumer,结果消费,(入参为结果或者异常),不返回新结果
exceptionally
任务异常,则执行Function,异常转换,入参为原任务的异常信息;
若原任务无异常,则返回原任务结果,即不执行转换
 

7. 合并多个complete为一个

方法
描述
allOf
合并多个complete为一个,等待全部完成
anyOf
anyOf合并多个complete为一个,等待其中之一完成
(1)allOf
  我们在处理业务时,有时会有多任务异步处理,同步返回结果的情况
  • 采用多线程执异步行某种任务,比如在不同主机查询磁盘列表信息。
  • 将执行结果搜集,分组分类,处理。
  • 将处理以后的结果给予展示。
(2)anyOf
  CompletableFuture. anyOf() 和其名字介绍的一样,当任何一个CompletableFuture完成的时候【相同的结果类型】,返回一个新的CompletableFuture。
  示例

三、其他相关api

1. future接口

(1)isDone()
  判断任务是否完成。三种完成情况:normally(正常执行完毕)、exceptionally(执行异常)、via cancellation(取消)
(2)get()
  阻塞获取结果或抛出受检测异常,需要显示进行try...catch处理。
(3)get(long timeout,TimeUnit unit)
  超时阻塞获取结果
(4)cancel(boolean mayInterruptIfRunning)
  取消任务,若一个任务未完成,则以CancellationException异常。其相关未完成的子任务也会以CompletionException结束
(5)isCancelled()
  是否已取消,在任务正常执行完成前取消,才为true。否则为false。

2. CompletableFuture接口

(1)join
阻塞获取结果或抛出非受检异常。
(2)getNow(T valueIfAbsent)
若当前任务无结果,则返回valueIfAbsent,否则返回已完成任务的结果。
(3)complete(T value)
设置任务结果,任务正常结束,之后的任务状态为已完成。
(4)completeExceptionally(Throwable ex)
设置任务异常结果,任务异常结束,之后的任务状态为已完成。
(5)isCompletedExceptionally()
判断任务是否异常结束。异常可能的原因有:取消、显示设置任务异常结果、任务动作执行异常等。
(6)getNumberOfDependents()
返回依赖当前任务的任务数量,主要用于监控。
(7)orTimeout(long timeout,TimeUnit unit) jdk9
设置任务完成超时时间,若在指定时间内未正常完成,则任务会以异常(TimeoutException)结束。
(8)completeOnTimeout(T value,long timeout,TimeUnit unit) jdk9
设置任务完成超时时间,若在指定时间内未正常完成,则以给定的value为任务结果

四、区别

(1)whenComplete和handle区别
  whenComplete handle 方法就类似于 try..catch..finanlly finally 代码块。无论是否发生异常,都将会执行的。这两个方法区别在于 handle 支持返回结果。
(2)thenApply与thenCompose的异同
对于thenApply,fn函数是一个对一个已完成的stage或者说CompletableFuture的的返回值进行计算、操作;
对于thenCompose,fn函数是对另一个CompletableFuture进行计算、操作。
(3)有无Async的区别
  没有Async的在CompleteableFuture调用它的线程定义的线程上运行,因此通常不知道在哪里执行该线程。如果结果已经可用,它可能会立即执行。
有Async的无论环境如何,都在环境定义的执行程序上运行。为此CompletableFuture通常ForkJoinPool.commonPool()。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值