java future专题 2-5 CompletableFuture源码探秘-高级用法(2)

 接上篇,本篇继续介绍CompletableFuture的高阶使用方式。

1.举例

1)supplyAsync配合allOf

CompletableFuture的supplyAsync配合allOf,将所有的future绑定到一起,然后所有都执行完之后触发对应操作,demo:

allOf方法内部调用了andTree方法,看方法注释,该方法会根据传入的参数递归生成一棵树

这段代码可能看起来有点绕,我们举个具体的例子,比如添加5个任务(举例5的原因是因为当任务数为偶数的时候,情况过于简单,奇数情况下任务为3太少,所以就选取了5,5个任务可以覆盖这段代码的每处逻辑),那么cfs是个size为5的数组,lo是0,hi是4,根据这组参数,树的构成逻辑如下:

根据0和4得到mid为2,对a来说,不满足lo和mid相等的条件,所以继续递归调用andTree方法,到下面0和2得到mid为1。对b来说,既不满足lo和hi相等的条件,也不满足hi和mid+1相等的条件,所以也继续递归调用andTree方法,到下面3和4得到mid为3。后续以此来推。经过递归最终生成的树如下图所示:

先解释下这棵树的画法,方形中的三个数字代表andTree方法中的lo,mid和hi,数字i的圆形代表cfs的第i个元素,即cfs[i]。那么根据这棵树,我们将任务两两组合了,一共生成了4个任务:

1)任务0和1组成一对,它们组合在一起起个名字叫做0-1,这里a=cfs[0],b=cfs[1],同时创建了一个叫做d的CompletableFuture,这里叫它d01,作为返回值

2)任务0-1又和任务2组成一对,起个名字叫做0-1-2,这里a=d01,b=cfs[2],同时创建一个CompletableFuture,这里叫它d012,作为返回值

3)任务3和任务4组成一对,叫做3-4,这里a=cfs[3],b=cfs[4],同时创建一个CompletableFuture,这里叫它d34,作为返回值

4)任务0-1-2和任务3-4组成一对,叫做0-1-2-3-4,这里a=d012,b=d34,同时创建一个CompletableFuture,这里叫它d01234。这个d01234就是demo中的最后一个future。

所以:

对1)来说,a=cfs[0],b=cfs[1]都完成之后,会触发d01。

对2)来说,d01和cfs[2]都执行完会触发d012。

对3)来说,a=cfs[3],b=cfs[4]都执行完会触发d34。

对4)来说,d012和d34都执行完之后会触发d01234。

除此之外,allOf得到的最后一个future的触发,是由最晚执行完的那个任务去触发的,从上面的demo中可以看出,打印hello这个任务的线程和最终future任务的线程是同一个线程。

2)supplyAsync配合anyOf

anyOf和allOf的区别,顾名思义,就是allOf是所有的任务都完成后出发最后一个future,anyOf是任何一个任务完成后就触发最后一个future。demo:

它的底层和allOf类似,也是根据传入的任务数量构造一个任务树,anyOf内部会调用orTree,这里和andTree不一样的地方是它内部构造了一个叫做OrRelay的对象,而andTree中构造的是一个叫做BiRelay的对象。那么这两个对象有什么区别呢?直接上源码:

它的tryFire实现里面调用的是orRelay方法,这里面和biRelay的区别如源码所示,orRelay判断两个任务的result都是null的时候才认为任务没有完成,换言之,任何一个任务完成了就去触发剩下的流程。而biRelay判断有任何一个result为空,就认为任务没有结束。

还有一个区别就是biPush方法和orPush方法

biPush是有任何一个任务没完成就压栈。orPush是两个任务都没完成的情况下才压栈。

除此之外,anyOf得到的最后一个future的触发,是由最早执行完的那个任务去触发的,这和allOf正好相反。从上面的demo中可以看出,打印world3这个任务的线程和最终future任务的线程是同一个线程。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值