future java 原理_如何理解scala的future和java的completableFuture?

从官方文档和例子入手,说一下我对两者的理解:

两者想解决的问题本质上是一样的,提供统一通用的基于异步的并发编程的抽象,从Java这个名字上可以猜到,Java里也是有Future的,只不过早期定义的Future只包装的异步计算的结果,并没有办法组合这些结果对其进行任何变换。可以看到Java里的Future仅仅定义了最基本的操作,

为了补全这个粗糙的接口,引入了新的接口CompletionStage,从方法表里可以看出,跟之前Java Future相比,它定义了许多新的功能,可以看到所有的接口都返回了新的Stage,这也是为了更好的和其他stage的编排。另外引入了更完备的异常处理机制,看着方法很多,抛开基于细粒度操作的组合,归纳起来就这么几个方面

结果的处理apply系列,返回结果基于 T->U 的变换,对应顺利执行结束的情况。

accept系列,返回结果基于 T-> Void的变换,从签名也可以看到所有的accept变换的结果都是CompletionStage。

then系列,这个系列比较多,这一类方法关心的是当前Stage正确退出之后的操作,基于不同定义方式,产生一个新的Stage。

考虑异常handle系列,升级版的apply,增加对异常的考虑,接受BiFunction多了一个Throwable作为类型参数。

when系列,同上与then相比,加上异常。

exceptionally,错误处理,如果出错用什么办法cover。

多个Stage交互runAfter系列,和另一个stage一起推导出下一个stage,三个stage的关系。

Either和Both,和runAfter配合表示两个并行的Stage到下一个Stage的条件是两者都完成还是任意一个完成

输入不同Combine和Compose,决定输入参数的不同,和Stage直接关联用Combine,和Function关联用Compose

对于异步的控制带async后缀的方法,计算时不会复用thread

带executor输入的方法,可以自行管理thread

扒完了CompletionStage,CompletableFuture 就是对Future和CompletionStage的实现。他提供了一些静态方法,方便你去创建Future

以上Java的CompletableFuture,你会发现它的方法还是难以改变传统Java Lib的思路,为了给开发行方便提供了各种功能的组合,用的时候一脸懵逼,不知道从哪里下手,但跟多线程编程的前辈们相比,比如Folk/Join,有太大的提升,

再来看看Scala的版本,不同的语言同样的思路,函数式编程占了便宜

异步编程的本质,是将耗时的操作和主线程(调度)分开,通过将计划去驱动执行,然而说的简单,做起来却不容易,因为实际的逻辑往往非常复杂,不仅要做到对执行模型的统一抽象,还要提供对底层的控制,很容易设计出臃肿的接口(Java退出了群聊)。但是!!大事化小,小事化函数,仅仅关心输入输出,通过强调结果和组合逻辑,仅仅用少量的代码就可以实现复杂的逻辑,这一点也是函数式编程所擅长的,从函数组合的角度来讲,可以延展到Monad,但是仅仅为了理解Future的核心,只需要知道For/FlatMap是干啥的就可以了,For Comprehensions

下面贴上Scala Future的核心方法,官方的分类,这里注意不要被polling误导了,Future的value是立即返回的,如果没有ready会返回None

注意到transformation里的基本操作map/flatMap/flatten/collect, 这些和Scala里的容器类保持一致,所以Future做的事情将函数执行结果放到一个容器里,这个容器实际上是Option[Try[T]],但大多数时候我们关注的是正确结果T的变换,所以map这些主要是对T进行操作。下面重点列出一些和Java不太一样的地方:异常只是一种特殊的返回结果,通过Try来封装,模式匹配Failure异常,Success正常结果,不用再考虑什么when/then的微妙区别了。而且理论上你可以用transform方法实现各种map/flatMap

Void不是一种特殊的输出,什么Consumer,BiConsumer不需要了,抹去了apply和accpet的区别,(Java :还是类型系统拖累了我)。

流定义,这里看到函数作为一等公民的优势,不在有绕口令一样的compose/combine/apply,通过for..yield或者flatMap语句实现Future之间自由组合。这里高亮一点,多个future的输出到下一个future,Java没有直接实现,另一方面,Scala版本并没有直接对Either逻辑的实现,需要通过onComplete手动实现。

执行的过程通过ExecutionContext管理,通过隐式参数来扩展。

总结:Scala的Future短小精悍,源码可读性非常高,如果你是想学习Future的原理,通过Scala能快速上手并且感受FP的威力。如果选择Java作为第一语言去了解Future,建议先了解下Java8 新增关于Lambda的部分,翻了源码才知道,这个CompletableFuture如此的复杂,原来当年Java不是不想做完Future,而是没有Function,谈何Future。

相关文档参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值