揭开Future的神秘面纱——任务执行
前言
此文承接之前的博文 解开Future的神秘面纱之取消任务 补充一些任务执行的一些细节,并从全局介绍程序的运行情况。
系列目录
- 揭开Future的神秘面纱——任务取消
- 揭开Future的神秘面纱——任务执行
- 揭开Future的神秘面纱——结果获取
任务的提交与执行
任务提交到执行的流程

前文我们已经了解到一些Future的实现细节,这里我们来梳理一下运行流程。注意:这里说的是提交(Submit),而不是执行(execute)
(1)客户端创建一个线程任务,即一个Callable或Runnable对象。
(2)客户端调用ExecutorService的submit方法,将任务提交给执行器。
(3)ExecutorService的具体类会将submit委托给AbstractExecutorService(具体类的父类)。
(4)父类submit方法将获取到的Runnable/Callable任务交由其内部方法newTaskFor进行包装。
(5)newTaskFor方法将Runnable/Callable包装成FutureTask对象。
(6)submit把包装好的FutureTask对象交由execute方法执行,此方法有ThreadPoolExecutor(具体类)提供。
(6)submit方法返回FutreTask对象引用给客户端。
任务提交为何能接收两种类型的接口?
FutureTask接收到Runnable对象后,会利用适配器,将其适配为Callable对象进行使用。注意,Runnable适配后,返回值基本没什么意义,都是写死的。

实际上很有意思的是,FutureTask只使用Callable对象(因为使用Future的初衷就是想要获取任务处理结果),而Executor的execute只接收Runnable对象(执行器只管执行任务)
FutureTask
FutureTask实际上相当于Runnable对象的装饰器,FutureTask的继承结构如图所示:

我们知道Runnable定义了任务该做什么,Future定义了任务的控制操作,而RunnableFuture接口兼具这两个功能。
Future就是实现这组操作的实现类,它也是Runnable的装饰器类,Runnable任务在经过其包装后,仍然还是Runnable,不影响其交给execute方法执行。而且他实现了Future接口,也就可以根据它对任务进行控制。
FutureTask有哪些字段,用来做什么的?

(1)state => 状态,用于基于状态的控制操作。
- NEW => 新建任务
- COMPLETING => 正在完成,即任务已经被线程启动
- NORMAL => 正常完成任务
- EXCEPTIONAL => 任务因为异常而终止
- CANCELLED => 任务已被取消,注意这里并不表示任务实际状态,即任务可能还在运行。
- INTERRUPTING => 中断任务中
- INTERRUPTD => 任务已被中断
(2)callable => callable任务,实际被执行的任务
(3)outcome => 执行结果
(4)runner => 执行线程的引用,用来控制任务的执行。
(5)waiters => 等待线程队列,当任务还未完成时,用于保存因为获取结果的而被阻塞的线程。
FutureTask的状态变化
(1)NEW -> COMPLETING -> NORMAL(任务正常执行到结束)
(2)NEW -> COMPLETING -> EXCEPTIONAL(任务执行过程中出现异常)
(3)NEW -> CANCELLED (任务被取消)
(4)NEW -> INTERRUPTING -> INTERRUPTED (任务已经开始,尚未完成就被取消)
FutureTask如何确定其执行线程的?
任务的控制最主要的两个功能就是取消和获取结果。取消的操作,上一篇博文已经讲到了,获取结果将于下篇讲述。这里补充前篇的一些内容,也就是取消操作相关的细节,当时已经获知,要取消任务,实际上是通过中断任务的执行线程实现的,如图:
FutureTask的cancel方法

但是,这个runner是何时被赋值的,我当时并不清楚,查阅源码也没发现什么setRunner之类的代码。后来突然想到,只有在任务被执行的时候才能知道,它到底被哪个线程执行。于是才注意到了这段CAS的代码,(当时不太懂,所以就算看到了这段代码,也不明白)。意思就是说,如果当前对象的runner字段值为null,就将其设置为当前的执行线程。到这里,我们就有了此线程的引用。


FutureTask到达ThreadPoolExecutor的execute之后,是什么情形?
这里简要说一下,任务到达ThreadPoolExecutor之后,线程池会根据当前线程数量的情况进行处理,可能创建一个新线程来执行,或者加入到任务队列等待执行,再或者就是被线程池抛弃等等。
相关细节可查看,我关于ThreadPoolExecutor的相关博文。
揭开Future的神秘面纱——任务执行的更多相关文章
- 揭开Future的神秘面纱——结果获取
前言 在前面的两篇博文中,已经介绍利用FutureTask任务的执行流程,以及利用其实现的cancel方法取消任务的情况.本篇就来介绍下,线程任务的结果获取. 系列目录 揭开Future的神秘面纱—— ...
- 揭开Future的神秘面纱——任务取消
系列目录: 揭开Future的神秘面纱——任务取消 揭开Future的神秘面纱——任务执行 揭开Future的神秘面纱——结果获取 使用案例 在之前写过的一篇随笔中已经提到了Future的应用场景和特 ...
- 解开Future的神秘面纱之任务执行
此文承接之前的博文 解开Future的神秘面纱之取消任务 补充一些任务执行的一些细节,并从全局介绍程序的运行情况. 任务提交到执行的流程 前文我们已经了解到一些Future的实现细节,这里我们来梳理一 ...
- ASP.NET 运行时详解 揭开请求过程神秘面纱
对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就 ...
- SparkSQL大数据实战:揭开Join的神秘面纱
本文来自 网易云社区 . Join操作是数据库和大数据计算中的高级特性,大多数场景都需要进行复杂的Join操作,本文从原理层面介绍了SparkSQL支持的常见Join算法及其适用场景. Join背景介 ...
- 从一个Demo开始,揭开Netty的神秘面纱
本文是Netty系列第5篇 上一篇文章我们对于I/O多路复用.Java NIO包 和 Netty 的关系有了全面的认识. 到目前为止,我们已经从I/O模型出发,逐步接触到了Netty框架.这个过程中, ...
- 带你揭开ATM的神秘面纱
相信大家都用过ATM取过money吧,但是有多少人真正是了解ATM的呢?相信除了ATM从业者外了解的人寥寥无几吧,鄙人作为一个从事ATM软件开发的伪专业人士就站在我的角度为大家揭开ATM的神秘面纱吧. ...
- 揭开HTTPS的神秘面纱
摘自:https://www.cnblogs.com/hujingnb/p/11789728.html 揭开HTTPS的神秘面纱 在说HTTP前,一定要先介绍一下HTTP,这家伙应该不用过多说明了 ...
- 揭开Docker的神秘面纱
Docker 相信在飞速发展的今天已经越来越火,它已成为如今各大企业都争相使用的技术.那么Docker 是什么呢?为什么这么多人开始使用Docker? 本节课我们将一起解开Docker的神秘面纱. 本 ...
随机推荐
- 《计算机科学基础》学习笔记_Part 1 Computer and Data
Technorati Tags: 计算机科学基础,读书笔记 Chapter 1. Introduction Ø 计算机:黑盒,Output Data=f(Input Data, Program) Ø ...
- codeblock快捷键使用
•在编辑区按住右键可拖动代码,省去拉滚动条之麻烦:相关设置:Mouse Drag Scrolling. •Ctrl+D可复制当前行或选中块. •可拖动选中块使其移动到新位置,按住Ctrl则为复制到新位 ...
- SRM476
250pt 题意:饲养N<=50只Badgers,每只食量是X[i],当没看到别的一只Badgers吃东西时,它的食量就会增加Y[i],现在一共用P的粮食,问最多能养的起多少只獾. 思路:枚举一 ...
- Java设计模式详尽资料
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- J - Oil Skimming 二分图的最大匹配
Description Thanks to a certain "green" resources company, there is a new profitable indus ...
- 关于DFS和BFS的理解 以及坐标的定义
http://blog.csdn.net/bool_isprime/article/details/5803018DFS: 1: 坐标类型搜索 :这种类型的搜索题目通常来说简单的比较简单,复杂的通常在 ...
- Martin Fowler 分层测试概念博文分享
在我们测试工作中,常常遇到这样的问题:开发与测试团队分属不同的不同(部门隔离.沟通不畅),质量职责划分不清(出现bug往往都是测试人员背锅),需求的不确定和易变性(需求不断变化导致代码不停更新.产品重 ...
- 输出的数据格式是如何决定的-------Asp.net WebAPI学习笔记(二)
在上一篇文章<路由其实也可以很简单>,我们解决了路由问题,这篇文章,我们来研究剩下的另一个问题,为何我们的方法返回的是一个列表,输出到客户端的时候,变成json呢,大家应该还记得我们上一篇 ...
- WPF 打印界面(控件)到A4纸
这次遇到一个需求,就是将整个界面打印在A4纸上. 需求清楚后,Bing一下关于打印,就找到一个类PrintDialog ,其中两个方法可能会用到: 特别是public void PrintVisual ...
- 多个文本框录入,使用回车键替找Tab键
为了快速把form的所有文框输入完毕,我们不必使用鼠标去focus文本框. 在html页中放几个文本框: <div class="DivInput"> <div& ...