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. Android服务之bindService源代码分析

    上一篇分析startService时没有画出调用ActivityManagerService之前的时序图,这里画出bindService的时序图.它们的调用流程是一致的. 先看ContextWrapp ...

  2. Java之基本类库学习

    JAVA基本类库: (一),输入相关 main(String[] args):设置输入参数 输入类:Scanner:Scanner sc=new Scanner(System.in); (二),系统相 ...

  3. ASP.NET MVC学习---(九)权限过滤机制(完结篇)

    相信对权限过滤大家伙都不陌生 用户要访问一个页面时 先对其权限进行判断并进行相应的处理动作 在webform中 最直接也是最原始的办法就是 在page_load事件中所有代码之前 先执行一个权限判断的 ...

  4. 【共享单车】—— React后台管理系统开发手记:AntD Form基础组件

    前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...

  5. Laravel之哈希/常用函数/分页

    一.哈希 1.简介Laravel Hash 门面为存储用户密码提供了安全的Bcrypt 哈希算法.如果你正在使用Laravel 应用自带的AuthController 控制器,将会自动为注册和认证使用 ...

  6. 借助backtrace和demangle实现异常类Exception

    C++的异常类是没有栈痕迹的,如果需要获取栈痕迹,需要使用以下函数: #include <execinfo.h> int backtrace(void **buffer, int size ...

  7. Android 虚线切割线

    drawable下新建一个虚线的xml.dash_line.xml <? xml version="1.0" encoding="utf-8"?> ...

  8. 如何为Apache JMeter开发插件(二)—第一个JMeter插件

    文章内容转载于:http://lib.csdn.net/article/softwaretest/25700,并且加上个人一些截图 本篇将开启为JMeter开发插件之旅,我们选择以Function(函 ...

  9. js中的四舍五入函数

    刚学到这部分时,感觉特别简单.可最近写个ajax分页时,忽然忘记应该怎么使用哪种函数来计算总的页数...哎,好记星不如烂笔头啊,还是老老实实的写下来吧.随时查看. 1.Math.ceil(x):对x向 ...

  10. PHP面试题及答案解析(1)—PHP语法基础

    1. strlen( )与 mb_strlen( )的作用分别是什么? strlen和mb_strlen都是用于获取字符串长度.strlen只针对单字节编码字符,也就是说它计算的是字符串的总字节数.如 ...