文章目录

  • Pre
  • 并行 VS 并发
  • Future接口
  • 使用 Future 以异步的方式执行一个耗时的操作
  • Future接口的局限性


Pre

并不希望因为等待某些服务的响应,阻塞应用程序的运行,浪费CPU时钟周期。

这些场景体现了多任务程序设计的另一面。我们前面学习的分支/合并框架以及并行流是实现并行处理的宝贵工具;它们将一个操作分为多个子操作,在多个不同的核、CPU甚至是机器上并行地执行这些子操作。

与此相反,如果你的意图是实现并发,而非并行,或者你的主要目标是在同一个CPU上执行几个松耦合的任务,充分利用CPU的核,让其足够忙碌,从而最大化程序的吞吐量,那么你其实真正想做的是避免因为等待远程服务的返回,或者对数据库的查询,而阻塞线程的执行,浪费宝贵的计算资源,因为这种等待的时间很可能相当长。

Future 接口,尤其是它的新版实现 CompletableFuture ,是处理这种情况的利器 .

并行 VS 并发


Future接口

Future 接口在Java 5中被引入,设计初衷是对将来某个时刻会发生的结果进行建模。它建模了一种异步计算,返回一个执行运算结果的引用,当运算结束后,这个引用被返回给调用方。

在Future 中触发那些潜在的耗时的操作把调用线程解放出来,让它能继续执行其他有价值的工作,不再需要呆呆的等待耗时的操作完成。

打个比方,你可以把它想象成这样的场景:你拿了一袋子衣服到干洗店洗。干洗店的员工会给你张发票,告诉你什么时候你的衣服会洗好(这就是一个 Future 事件) 。 衣服干洗的同时,你可以去做其他的事情。

Future 的另一个优点是它比更底层的 Thread 更易用。要使用 Future ,通常你只需要将耗时的操作封装在一个 Callable 对象中,再将它提交给 ExecutorService ,就OK了。

来看下例子


import java.util.concurrent.*;/*** @author 小工匠* @version 1.0* @description: TODO* @date 2021/4/5 9:47* @mark: show me the code , change the world*/
public class FutureTest {public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {ExecutorService executorService = Executors.newSingleThreadExecutor();Future<String> future = executorService.submit(() -> {try {TimeUnit.SECONDS.sleep(2);return "I'm OK ";} catch (InterruptedException e) {return "I'm Error ";}});while(!future.isDone()){Thread.sleep(10);}// 超时时间的阻塞// future.get(10,TimeUnit.SECONDS);// 调用get 阻塞System.out.println(future.get());executorService.shutdown();}
}

使用 Future 以异步的方式执行一个耗时的操作

这种编程方式让你的线程可以在 ExecutorService 以并发方式调用另一个线程执行耗时操作的同时,去执行一些其他的任务。

接着,如果你已经运行到没有异步操作的结果就无法继续任何有意义的工作时,可以调用它的 get 方法去获取操作的结果。

如果操作已经完成,该方法会里立刻返回操作的结果,否则它会阻塞你的线程,直到操作完成,返回相应的结果。

你能想象这种场景存在怎样的问题吗?如果该长时间运行的操作永远远不返回了会怎样?为了处理这种可能性,虽然 Future 提供了一个无需任何参数的 get 方法,我们还是推荐大家使用重载版本的 get 方法,它接受一个超时的参数,通过它,你可以定义你的线程等待 Future 结果的最长时间,而不是一直等待下去。

【使用 Future 以异步方式执行长时间的操作】


Future接口的局限性

通过上面的例子,我们知道 Future 接口提供了方法来检测异步计算是否已经结束(使用isDone 方法),等待异步操作结束 ,以及获取计算的结果。

但是这些特性还不足以让你编写简洁的并发代码。比如,我们很难表述 Future 结果之间的依赖性;从文字描述上这很简单,“当长时间计算任务完成时,请将该计算的结果通知到另一个长时间运行的计算任务,这两个计算任务都完成后,将计算的结果与另一个查询操作结果合并”。

但是,使用 Future 中提供的方法完成这样的操作又是另外一回事。这也是我们需要更具描述能力的特性的原因,比如下面这些。

  • 将两个异步计算合并为一个——这两个异步计算之间相互独立,同时第二个又依赖于第一个的结果
  • 等待 Future 集合中的所有任务都完成。
  • 仅等待 Future 集合中最快结束的任务完成(有可能因为它们试图通过不同的方式计算同一个值),并返回它的结果。
  • 通过编程方式完成一个 Future 任务的执行(即以手工设定异步操作结果的方式)。
  • 应对 Future 的完成事件(即当 Future 的完成事件发生时会收到通知,并能使用 Future计算的结果进行下一步的操作,不只是简单地阻塞等待操作的结果)。

了解新的 CompletableFuture 类(它实现了 Future 接口)如何利用Java 8的新特性以更直观的方式将上述需求都变为可能。

Stream 和 CompletableFuture 的设计都遵循了类似的模式:它们都使用了Lambda表达式以及流水线的思想。

从这个角度,你可以说CompletableFuture 和 Future 的关系就跟 Stream 和 Collection 的关系一样。

Java8 - Future 接口相关推荐

  1. 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )

    文章目录 一.Future 接口 1.Future 接口简介 2.取消任务方法 3.Future 接口源码注释 二.Callable 接口 三.Runnable 接口 上一篇博客 [Android 异 ...

  2. Callable和Future接口的实现

    一.Callable和Future Callable接口定义了一个call方法可以作为线程的执行体,但call方法比run方法更强大: call方法可以有返回值 call方法可以申明抛出异常 Call ...

  3. Java基础知识强化之网络编程笔记25:Android网络通信之 Future接口介绍(Java程序执行超时)...

    1. Future接口简介 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API ...

  4. Callable接口、Runable接口、Future接口

    转自:https://www.cnblogs.com/felixzh/p/6044371.html 参考:https://blog.csdn.net/qq_36761831/article/detai ...

  5. 以两种异步模型应用案例,深度解析Future接口

    摘要:本文以实际案例的形式分析了两种异步模型,并从源码角度深度解析Future接口和FutureTask类. 本文分享自华为云社区<[精通高并发系列]两种异步模型与深度解析Future接口(一) ...

  6. java8函数式接口_java8的函数式接口

    函数式接口 就是在java8里允许你为一个接口(只有一个实现的,声明为FunctionalInterface注解的)实现一个匿名的对象,大叔感觉它与.net平台的委托很类似,一个方法里允许你接收一个方 ...

  7. java future接口_java Future 接口介绍

    在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API的一部分,在java.uti ...

  8. Future 接口介绍

    2019独角兽企业重金招聘Python工程师标准>>> Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务.期间我自己可以去做任何想做的 ...

  9. Java并发编程-Executor框架之Callable和Future接口

    在上一篇文章中我们已经了解了Executor框架进行线程管理,这篇文章将学习Executor框架的另一个特性,我们知道执行Runnable任务是没有返回值得,但Executor可以运行并发任务并获得返 ...

最新文章

  1. 设置树莓派的无线网卡为监听模式(monitor)
  2. sylog mysql_25.2 配置使用基于mysql存储日志信息
  3. python 大小端转换,大小端 python
  4. G盘文件系统损坏要如何恢复数据
  5. oracle11g日志分析,Oracle11g在Windows环境下监听日志文件达到4G问题解决方案
  6. 【转】【开源专访】谢宝友:会说话的Linux内核
  7. R语言 | 构建信用评分卡模型
  8. long 雪花算法_为什么 MySQL 不推荐使用 uuid 或者雪花 id 作为主键?
  9. 激光实现3D空气成像技术,无需屏幕
  10. 网路收报流程-网桥的处理流程(br网桥)(四)
  11. 苹果电脑上几款不错的矢量绘图工具
  12. 知识驱动的主动式开放域对话系统 by 车万翔 2020/4/11
  13. oracle数据库单张表备份,oracle数据库如何备份一张表
  14. thinkphp5 excel导入导出
  15. 《华为工作法》6 华为的成功不是一个人的
  16. unity商店的Standard Assets自带人物移动插件的bug修改
  17. 点燃我温暖你 爱心代码python
  18. html5获取我的位置并在百度地图上显示
  19. 逆向笔记2(数据宽度_逻辑运算)
  20. NLP词向量模型总结:从Elmo到GPT,再到Bert

热门文章

  1. 远程计算机串口控制软件,智能控制的设备上使用远程开关需要用到RS485串口继电器、网关、电脑平台...
  2. Pytorch学习:Task4 PyTorch激活函数原理和使用
  3. visual studio 2019配置OnnxRuntime+推理+vgg16
  4. python 去除字符串里所有标点符号
  5. html 书架样式css,CSS3 响应式书架布局
  6. 剪切粘贴时总是上次的内容_【Procreate 迷你课堂】#4 三指快速拷贝及粘贴
  7. Leetcode 876. 链表的中间结点 (每日一题 20210918)
  8. LeetCode面试刷题技巧-二分查找算法代码思路解析
  9. tableau可视化数据分析60讲(十七)-tableau常用可视化视图(凹凸图甘特图直方图)
  10. TensorFlow在windows 下的安装