转载

从 Future 到 CompletionStage 的一些理解

Future是Java Concurrent Util包中定义的一个接口,它是一个很有意思的发明,我们先来看看Future接口注释中的一段示例代码:

从 Future 到 CompletionStage 的一些理解

引自Future接口注释

这里试着站在ExecutorService的角度来描述一下Future多定义的能力: 我不能立即给你想要的结果,但是我可以给你一个有关将来的承诺,而你不需要一直在这里等着我,因为我能理解你也有你要做的事情,等你忙完你的事情之后,可以再来找我,届时你可以问我我有没有完成你交给我的任务,如果还没有完成的话,你还可以再去忙你的事情,当然如果你愿意的话,也可以一直等着我,直到我好了为止,但我并不建议你这么做,因为等待这件事情真的非常浪费时间。

在Java编程中,Future可以很好地解决等待阻塞的问题,因为任务执行器给到客户端的不是立即的结果,而是一个“有关将来的承诺”,客户端拿到这个承诺之后可以随时来询问结果,不需要一直等待。可以说Future真的是一个非常巧妙抽象,客观地反应了真实世界中发生的类似的事情。 但是在实际应用中我们发现Future仍然存在一些缺陷 ,怎么说呢? 因为Future没有考虑到、或者也可能是考虑到了但是并没有解决在实际应用场景中存在的一个问题,而这个问题来源于这样的一个事实: 任务不是孤立存在的,任务之间往往是有依赖关系的。 基于Future接口编程的情况下,如果要做到效率最优,比如任务的总执行时间最优,客户端要自己来实现任务的编排,那么在自己处理这些逻辑的情况下,代码中就会充斥着“ 如果某个任务还没有完成,则去忙别的事情,等一会再看看 ”这样的逻辑,而在实际业务场景中,任务的多寡与任务的执行时间是动态且不可枚举的,总的来说基于Future编程要实现任务执行最优具有较高的编程复杂度度。

因此,JDK8定义了CompletionStage这样的接口作为Future的补充,“Stage”直译的话代表的是“阶段”或“步骤”,“Completion”代表的是客户端可以感知到任务什么时候执行完成,这里的“ 完成 ”有三层含义: 成功完成、异常退出和取消。 简单一点我们可以将Stage等价于一个常规的异步任务,“阶段”这个抽象的概念隐含着第二层意思是 多个任务之上有一个“大的任务”存在,而任务只是这个“大的任务”的不同“ 阶段 ”而已,同时不同任务之间是有依赖关系的 ,换句话说, Complet ionStage的出现意味着JDK愿意帮客户端解决上一节中我们提到的实际问题。下面 列举了一些常见的依赖模式:

1)一个任务的执行可能依赖另一个任务执行的结果;

2)一个任务的执行可能依赖多个任务的执行结果;

3)一个任务不依赖前一个任务的结果,但是希望在这个任务完成之后立即开始;

4)……

基于CompletionStage的能力,我们不再需要自己轮训,可以在编程的时候直接指定当某个“阶段”完成之后要开始的任务,以及上面提到的更复杂的模式包括指定多个“阶段”完成之后要开始的任务。

从 Future 到 CompletionStage 的一些理解

从 Future 到 CompletionStage 的一些理解

原文  https://mp.weixin.qq.com/s/EsNVRYausaW2oU_yiQFtcg
正文到此结束
Loading...