`
teamojiao
  • 浏览: 344331 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论
阅读更多

什么是Future?

用过Java并发包的朋友或许对Future (interface) 已经比较熟悉了,其实Future 本身是一种被广泛运用的并发设计模式,可在很大程度上简化需要数据流同步的并发应用开发。在一些领域语言(如Alice ML )中甚至直接于语法层面支持Future。

这里就以java.util.concurrent.Future 为 例简单说一下Future的具体工作方式。Future对象本身可以看作是一个显式的引用,一个对异步处理结果的引用。由于其异步性质,在创建之初,它所 引用的对象可能还并不可用(比如尚在运算中,网络传输中或等待中)。这时,得到Future的程序流程如果并不急于使用Future所引用的对象,那么它 可以做其它任何想做的事儿,当流程进行到需要Future背后引用的对象时,可能有两种情况:

  • 希望能看到这个对象可用,并完成一些相关的后续流程。如果实在不可用,也可以进入其它分支流程。
  • “没有你我的人生就会失去意义,所以就算海枯石烂,我也要等到你。”(当然,如果实在没有毅力枯等下去,设一个超时也是可以理解的)

对于前一种情况,可以通过调用Future.isDone()判断引用的对象是否就绪,并采取不同的处理;而后一种情况则只需调用get()或
get(long timeout, TimeUnit unit)通过同步阻塞方式等待对象就绪。实际运行期是阻塞还是立即返回就取决于get()的调用时机和对象就绪的先后了。(如下图所示)

 


 

简单而言,Future模式可以在连续流程中满足数据驱动的并发需求,既获得了并发执行的性能提升,又不失连续流程的简洁优雅。

与其它并发设计模式的对比

除了Future外,其它比较常见的并发设计模式还包括“回调驱动(多线程环境下)”、“消息/事件驱动(Actor模型中)”等。

回调是最常见的异步并发模式,它有即时性高、接口设计简单等有点。但相对于Future,其缺点也非常明显。首先,多线程环境下的回调一般是在触发 回调的模块线程中执行的,这就意味着编写回调方法时通常必须考虑线程互斥问题;其次,回调方式接口的提供者在本模块的线程中执行用户应用的回调也是相对不 安全的,因为你无法确定它会花费多长时间或出现什么异常,从而可能间接导致本模块的即时性和可靠性受影响;再者,使用回调接口不利于顺序流程的开发,因为 回调方法的执行是孤立的,要与正常流程汇合是比较困难的。因此回调接口适合于在回调中只需要完成简单任务,并且不必与其它流程汇合的场景。

上述这些回调模式的缺点恰恰正是Future的长项。由于Future的使用是将异步的数据驱动天然的融入顺序流程中,因此你完全不必考虑线程互斥 问题,Future甚至可以在单线程的程序模型(例如协程)中实现(参见下文将要提到的“Lazy Future”)。另一方面,提供Future接口的模块完全不必担心像回调接口那样的可靠性问题和可能对本模块的即时性影响。

另一类常见的并发设计模式是“消息(事件)驱动”,它一般运用在Actor模型中:服务请求者向服务提供者发送消息,然后继续进行后续不依赖服务处 理结果的任务,在需要依赖结果前终止当前流程并记录状态;在等到回应消息后根据记录的状态触发后续流程。这种基于状态机的并发控制虽然比回调更适合于有延 续性的顺序流程,但开发者却不得不将连续流程按照异步服务的调用切断为多个按状态区分的子流程,这样又人为的增加了开发的复杂性。运用Future模式可 以避免这个问题,不必为了异步调用而打碎连续的流程。但是有一点应当特别注意:Future.get()方法可能会阻塞线程的执行,所以它通常无法直接融 入常规的Actor模型中。(基于协程的Actor模型可以较好的解决这个冲突)

Future的灵活性还体现在其同步和异步的自由取舍,开发者可以根据流程的需要自由决定是否需要等待[Future.isDone()],何时等 待[Future.get()],等待多久[Future.get(timeout)]。比如可以根据数据是否就绪而决定要不要借这个空档完成点其它任 务,这对于实现“异步分支预测”机制是相当方便的。

Future的衍生

除了上面提到的基础形态之外,Future还有丰富的衍生变化,这里就列举几个常见的。

  • Lazy Future

与一般的Future不同,Lazy Future在创建之初不会主动开始准备引用的对象,而是等到请求对象时才开始相应的工作。因此,Lazy Future本身并不是为了实现并发,而是以节约不必要的运算资源为出发点,效果上与Lambda/Closure类似。例如设计某些API时,你可能需 要返回一组信息,而其中某些信息的计算可能会耗费可观的资源。但调用者不一定都关心所有的这些信息,因此将那些需要耗费较多资源的对象以Lazy Future的形式提供,可以在调用者不需要用到特定的信息时节省资源。

另外Lazy Future也可以用于避免过早的获取或锁定资源而产生的不必要的互斥。

  • Promise

Promise可以看作是Future的一个特殊分支,常见的Future一般是由服务调用者直接触发异步处理流程,比如调用服务时立即触发处理或 Lazy Future的取值时触发处理。但Promise则用于显式表示那些异步流程并不直接由服务调用者触发的情景。例如Future接口的定时控制,其异步流 程不是由调用者,而是由系统时钟触发,再比如淘宝的分布式订阅框架提供的Future式订阅接口,其等待数据的可用性不是由订阅者决定,而在于发布者何时 发布或更新数据。因此,相对于标准的Future,Promise接口一般会多出一个set()或fulfill()接口。

  • 可复用的Future

常规的Future是一次性的,也就是说当你获得了异步的处理结果后,Future对象本身就失去意义了。但经过特殊设计的Future也可以实现 复用,这对于可多次变更的数据显得非常有用。例如前面提到的淘宝分布式订阅框架所提供的Future式接口,它允许多次调用waitNext()方法(相 当于Future.get()),每次调用时是否阻塞取决于在上次调用后是否又有数据发布,如果尚无更新,则阻塞直到下一次的数据发布。这样设计的好处 是,接口的使用者可以在其任何合适的时机,或者直接简单的在独立的线程中通过一个无限循环响应订阅数据的变化,同时还可兼顾其它定时任务,甚至同时等待多 个Future。简化的例子如下:

for (;;) {
  schedule = getNextScheduledTaskTime();
  while(schedule > now()) {
    try {
      data = subscription.waitNext(schedule - now());
      processData(data);
    } catch(Exception e) {...}
  }
  doScheduledTask();
}
  • 大小: 37.8 KB
  • 大小: 37.8 KB
分享到:
评论

相关推荐

    The Future of Retail

    The Future of Retail - To the extent that there are two distinct sides to the argument, the position of Offline-to-Online (O2O) advocates is that, as more offline retailers are closing, brick-and-...

    八年级英语上册Unit5MyFuture阅读理解新版冀教版

    八年级英语上册Unit5MyFuture阅读理解新版冀教版

    Language Models:Past, Present, and Future.pdf

    例如,可以利用 BERT 模型来实现比人类更高的语言理解性能。我们还可以利用 GPT-3 模型生成类似人类写的文章。预训练语言模型的第二个优点是它们是通用的语言处理工具。在传统的自然语言处理中,为了执行机器学习...

    Peeking into the Future.rar

    内部包含论文Peeking into the Future Predicting Future Person Activities and Locations in Videos ()pdf格式)、中文翻译(不全)、自己为了理解写的PPT及论文对应代码

    Causal Recommendation:Progresses and Future Directions.pdf

    然而,由于缺乏对这一课题的系统概述,导致研究者和实践者难以理解和跟上这一方向。 在本教程中,我们将介绍因果关系的关键概念,并对因果推荐方面的现有工作进行系统回顾。我们将介绍来自两种不同因果框架的现有...

    总结了Thread-Callable-Future的小demo

    自留demo,主要是Thread-Callable-Future的基本实现。 参考文章: 1、深入理解Callable ...2、彻底理解Java的Future模式: https://www.cnblogs.com/cz123/p/7693064.html

    Machine Learning in Chemistry now and in the future.pdf

    【Jon Paul Janet】机器学习化学应用 最近机器学习或人工智能的视觉和自然语言处理方面的进展使个人助理或自动驾驶汽车等新技术的发展成为可能...《化学中的机器学习》关注以下内容,以启动您对这一高度相关主题的理解

    深入理解计算机系统(英文版)

    Contents Preface i 1 Introduction 1 1.1 Information isBits inContext . . . . . . ....1.2 Programs areTranslated byOtherPrograms intoDifferent Forms ....1.3 ItPays toUnderstandHowCompilation SystemsWork ....

    Future-Hand-Prediction

    PySlowFast PySlowFast是FAIR的开源视频理解代码库,可提供经过有效培训的最新视频分类模型。 该存储库包括以下方法的实现:介绍PySlowFast的目标是提供一种高性能,轻量级的pytorch代码库,该代码库提供了最新的...

    Benchmarking_past_present_future:基准测试工作坊首页:过去,现在和未来

    Benchmarking_past_present_future 基准测试研讨会主页:过去,现在和将来 我们去过哪里,我们要去哪里? 谈论过去比谈论未来要容​​易。 如今,基准从底向上发展(例如带有代码的论文)。 曾经有来自政府的更多...

    C语言课件 输入输出

    不同的专家学者对这个“差”有不同的理解,有共识也有争论。本书讨论了物联网的起源与发展、核心技术、主要特点以及应用前景,为读者勾画出一个具有鲜明特征的物联网时代。本书系统地阐述了物联网的层次结构和功能...

    TextRank算法原理介绍及实例.zip

    原理理解 # 1.1 textrank原理见 Textrank.docx ## 1.2 代码见: ```python #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import sys from ...

    understanding of active noise cancellation 理解噪声控制

    1.5 THE FUTURE .......................................................................................... 6 CHAPTER TWO. FOUNDATIONS OF ACTIVE CONTROL ....................... 9 2.1 PHYSICAL MECHANISMS...

    Java并发编程原理与实战

    Future设计模式实现(实现类似于JDK提供的Future).mp4 Future源码解读.mp4 ForkJoin框架详解.mp4 同步容器与并发容器.mp4 并发容器CopyOnWriteArrayList原理与使用.mp4 并发容器ConcurrentLinkedQueue原理与使用....

    io:java io学习项目

    Unix Domain Socket熟悉Linux下命令行工具深入理解进程,线程了解Java内存模型了解Java的并发包,如锁,读写锁,Barrier,Executer和Future了解Java 8的Lambda表达式和Streaming API理解TCP/IP协议族理解HTTP协议和...

    时态逻辑方法

    1. Contract-based design 2. Temporal Logics 3. Contract-based design with temporal logics 4. OCRA: tool support and applications 5. Conclusions and future directions

    future-of-modules:js模块的未来

    该示例很小,只需几分钟即可理解。笔记在我写这篇演讲时,这些链接非常有帮助,我建议他们进一步阅读: 未知的 的猴子补丁精神! 所有图像均来自第十二医生。 好吧,除了马尔科姆·塔克(Malcolm Tucker)之一。

    The hub network design problem

    Hub(枢纽,或转运中心)允许通过货物...轴辐式网络的设计本质和难度取决于分析人员的判断和决策,以及对以上问题的理解和关注。 我们通过对研究文献的分析回顾,并给出八个不同的网络设计协议的例子和简短的实验性案例。

    JAVA高质量并发详解,多线程并发深入讲解

    例如,通过讲解线程池、Future模式、Fork/Join框架等,帮助读者解决复杂的并发问题,提高系统的响应能力和吞吐量。此外,书中还深入剖析了并发编程中的常见问题,如死锁、活锁、饥饿等,并提供了相应的解决方案和...

    A_Yen_For_The_Future:日元的时间序列分析

    结果,他们一直在寻找可以帮助他们更好地理解各种货币的未来方向和风险的任何东西。 对冲基金也对任何能使他们在预测货币走势方面保持一致优势的东西都非常感兴趣。 在此分析中,我将使用ARMA,ARIMA和GARCH模型...

Global site tag (gtag.js) - Google Analytics