1 为什么需要Callable和Future

Runnable没有返回值,也不抛异常,这样主线程不能知道子线程的执行结果。

为了解决这个问题就有了Callable和Future。Callable提供的call方法返回一个结果,然后把这个结果交给Future,主线程通过Future就能够获取子线程执行的结果了。

Callable给子线程提供入参,Future提供子线程的返回值。FutureTask合二为一,它把Callable作为成员保存起来,而它本身就是一个Future。

2 什么是Future

Future被用来表示一个异步计算的未来结果。

Future提供了5个接口来查询异步任务的计算结果:

isDone:是否执行完了。

两个get,一个阻塞,一个计时阻塞。

cancel,取消任务的执行。

isCanceled,查询任务是否取消了执行。

3 Future有什么用

3.1 异步调用和并发

耗时的计算适用于异步和Future。

3.2 Future异步计算的使用举例

计算密集的任务;

处理大的数据结构;

远程方法调用:下载文件、web服务等

4 Future是如何实现的

Future能实现本质上是因为java的对象都是放在堆上的。FutureTask是在主线程中创建的对象,将之交给其它线程或者线程池去执行,线程执行完了之后,有一个返回值,将该返回值放在FutureTask的成员outcome上。然后,FutureTask再提供get函数来给主线程获取这个执行的结果。

4.1 FutureTask get实现的原理

第一,维护一个状态机,用户调用get之后,根据不同的执行状态,返回不同的值。

第二,如果任务还没有执行完,就把该线程放入等待队列,并且调用LockSupport.park()函数让阻塞该线程,这样get就阻塞了。

第三,在任务执行完了之后,会把这些等待队列中的线程踢出,并且调用LockSupport.unpark()函数解除阻塞,线程被唤醒。

5 Runnable和Callable比较

5.1 相同点

Runnable和Callable都提供线程的执行体。

5.2 Runable不提供返回值,也不抛异常。Callable提供返回值,可能会抛一个异常

比如FutureTask实现了Callable接口,call方法执行了之后将结果放在FutureTask的outcome成员中。

调用get的时候,如果执行体正常执行则返回该outcome,如果不正常执行就返回Exception。

6 Callable的使用场景

6.1 和Thread一起使用

需要一个中间人FutureTask,该类实现了Runnable和Future接口。因为实现了Runnable接口,因此可以作为参数传给Thread,创建一个新的thread。

FutureTask也可以作为参数传给线程池。

7 总结一下

Callable和Future一起使用来获取异步执行的结果。Callable作为入参,提供线程的执行体和该异步计算的返回值。Future作为异步计算的返回结果。

8 grpc中对Future的使用,grpc是如何通过Future来实现对异步调用结果的获取的?

异步调用时,服务器端调用执行完了,执行的结果是如何交给客户端的?

io是netty实现的,服务器端的调用执行之后,通过通道告知客户端,然后客户端就调用相应的listener。netty的服务器端和客户端都是有多路复用器的。用于监听各个IO事件。

10  参考资料

10.1 https://www.baeldung.com/java-future

10.2 https://www.geeksforgeeks.org/callable-future-java/

10.3 https://blog.csdn.net/codershamo/article/details/51901057

关于Future的更多相关文章

  1. 面向未来的友好设计:Future Friendly

    一年前翻译了本文的一部分,最近终于翻译完成.虽然此设计思想的提出已经好几年了,但是还是觉得应该在国内推广一下,让大家知道“内容策略”,“移动优先”,“响应式设计”,“原子设计”等设计思想和技术的根源. ...

  2. 线程笔记:Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  3. 第二篇 Entity Framework Plus 之 Query Future

    从性能的角度出发,能够减少 增,删,改,查,跟数据库打交道次数,肯定是对性能会有所提升的(这里单纯是数据库部分). 今天主要怎样减少Entity Framework查询跟数据库打交道的次数,来提高查询 ...

  4. Eclipse调试Android App若选择“Use same device for future launches”就再也无法选择其他设备的问题

    在狂批了某供应商的多媒体控制App有多烂后,夸下海口自己要做一个也是分分钟的事.当然要做好不容易,要超过他们的烂软件还是有信心的.过程中遇到各种坑,其中之一如下 刚开始只使用一个平板进行调试,老是弹出 ...

  5. java Future 接口介绍

    (转自:http://blog.csdn.net/yangyan19870319/article/details/6093481) 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java ...

  6. java多线程系类:JUC线程池:06之Callable和Future(转)

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  7. 架构师养成记--9.future模式讲解

    什么是future模式呢?解释这个概念之前我们先来了解一个场景吧,财务系统的结账功能,这个功能可能是每个月用一次,在这一个月中相关的数据量已经积累得非常大,这一个功能需要调用好几个存储过程来完成.假如 ...

  8. Future和Promise

    Future用于获取异步操作的结果,而Promise则比较抽象,无法直接猜测出其功能. Future Future最早来源于JDK的java.util.concurrent.Future,它用于代表异 ...

  9. Java--Callable与返回值future

    package com; import java.util.concurrent.*; /** * Created by yangyu on 16/11/28. */ /** * Callable a ...

  10. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

随机推荐

  1. 利用yarn多队列实现hadoop资源隔离

    大数据处理离不开hadoop集群的部署和管理,对于本来硬件资源就不多的创业团队来说,做好资源的共享和隔离是很有必要的,毕竟不像BAT那么豪,那么怎么样能把有限的节点同时分享给多组用户使用而且互不影响呢 ...

  2. Windows无法删除文件 提示找不到该项目怎么办

    1 如图所示,我想要删除某个文件,提示如图所示,一般用360的强力删除也不管用.   2 在桌面新建一个文本文档,并输入以下内容.保存为bat格式(比如Delete.bat).然后把这个删不掉的文件拖 ...

  3. K-近邻算法的Python实现 : 源代码分析

    网上介绍K-近邻算法的样例非常多.其Python实现版本号基本都是来自于机器学习的入门书籍<机器学习实战>,尽管K-近邻算法本身非常easy,但非常多刚開始学习的人对其Python版本号的 ...

  4. Java 调用存储过程、函数

     一.Java调用存储Oracle存储过程 测试用表: --创建用户表 create table USERINFO ( username ) not null, password ) not null ...

  5. DialogFragment创建默认dialog

    代码地址如下:http://www.demodashi.com/demo/12228.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 前言 在我们项目的进行中不可避免 ...

  6. Android开发过程中遇到的问题集合(—)

    1. Re-installation failed due to different application signatures. 将原来的软件包删除掉,然后又一次安装一次就好了.在命令行上执行:a ...

  7. CentOS6安装和卸载docker

    系统版本 [root@bogon yum.repos.d]# uname -a Linux bogon 2.6.32-642.el6.x86_64 #1 SMP Tue May 10 17:27:01 ...

  8. 配置YUM源更新源

    在虚拟机上更新yum,总是告诉我找不懂镜像服务器地址,配置失败,连 #yum install yum 它自己都无法更新. 于是决定先配置一下yum的更新源. 首先找到yum的主要配置文件, 一般在/e ...

  9. 在Vue中使用layer.js弹出层插件

    layer.js(mobile)是一个小巧方便的弹出层插件,在之前的apicloud项目中被大量使用,但最近对apicloud的IDE.非常不友好的文档和极低的开发效率深感厌烦,决定弃用然后转向Vue ...

  10. [译]GLUT教程 - 移动镜头1

    Lighthouse3d.com >> GLUT Tutorial >> Input >> Move the Camera I 下面来看一个更有趣的GLUT应用.本 ...