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. boolean类型的特殊的get和set方法

    public class D { private boolean a; public boolean isA() { return a; } public void setA(boolean a) { ...

  2. 2017.5.16 comparator和comparable的比较及使用

    参考来自: http://blog.csdn.net/lifuxiangcaohui/article/details/41543347 http://www.cnblogs.com/liuyuanyu ...

  3. 倍福TwinCAT(贝福Beckhoff)基础教程2.2 TwinCAT常见类型使用和转换_函数块

    右击POUs,添加一个FB功能块,相比于FUN,FB功能块有INPUT,OUTPUT,还有VAR,即FB可以有多个输出,但是整个FB没有返回值   实现相同的功能,FB要比FUN难看的多,FB要声明实 ...

  4. hbuilder - wap to app

    官方文档: http://www.dcloud.io/wap2app.html 新建Wap2App,示例网址:www.baidu.com 随后,我们可以在 最后,我们可以 打包完成以后,下载即可

  5. springboot缓存及连接池配置

    参见https://coding.imooc.com/lesson/117.html#mid=6412 1.springboot的springweb自己默认以及配置好了缓存,只需要在主文件(XxxAp ...

  6. 编辑mac系统环境变量后保存,提示没有权限用到下面这个命令

    编辑的文件是vim /etc/paths :w !sudo tee % %代表当前编辑文件名 MAC:查看端口占用情况: lsof -i tcp: list open files lsof -i 用以 ...

  7. git个人使用总结(命令版)

    一.基础命令 快照类操作:add.status.diff.commit.reset.rm.mv 分支类基本操作:branch.checkout.log.stash 分享及更新项目基本操作:pull.p ...

  8. jira报错,此域不支持您输入的日期

    jira报错,此域不支持您输入的日期 解决方法: 使用20117-1-1这样的格式输入,不要用选择日期.具体原因未知.

  9. AIX 安装标准

    文件夹 一.网卡需求 二.光纤卡需求 三.磁盘需求 四.主机文件系统需求 五.主机名命名规范 六.安装设置规范 七.參数改动规范 八.时钟同步设置 九.rootvg做镜像 十.AIX系统安全加固 一. ...

  10. go http请求基础

    1.请求方法: get post get 加请求参数,请求参数会加到url后面 post加请求参数,请求参数会放在body里面 请求方式:1.直接在url后面加参数  如:http://www.tes ...