futuretask使用_JDK源码分析-FutureTask
1. 概述
FutureTask 是一个可取消的、异步执行任务的类,它的继承结构如下:
它实现了 RunnableFuture 接口,而该接口又继承了 Runnable 接口和 Future 接口,因此 FutureTask 也具有这两个接口所定义的特征。FutureTask 的主要功能:
- 异步执行任务,并且任务只执行一次;
- 监控任务是否完成、取消任务;
- 获取任务执行结果。
下面分析其代码实现。
2. 代码分析
2.1 RunnableFuture 接口
分析 FutureTask 的代码之前,先看下它实现的接口。RunnableFuture 接口定义如下:
public
RunnableFuture 接口继承了 Runnable 接口和 Future 接口,而 Runnable 接口只有一个 run 方法,这里不再赘述。下面分析 Future 接口。
2.2 Future 接口
Future 接口方法定义如下:
主要方法分析:
/*
2.3 FutureTask 代码分析
- 任务的状态变量
// 任务的状态
其中 state 表示任务的状态,总共有 7 种,它们之间的状态转换可能有以下 4 种情况:
- 任务执行正常:NEW -> COMPLETING -> NORMAL
- 任务执行异常:NEW -> COMPLETING -> EXCEPTIONAL
- 任务取消:NEW -> CANCELLED
- 任务中断:NEW -> INTERRUPTING -> INTERRUPTED
示意图:
- WaitNode 类
在分析其他成员变量之前,先看一个内部嵌套类 WaitNode:
static
代码比较简单,就是对 Thread 的封装,可以理解为单链表的节点。
- 其他成员变量
/** The underlying callable; nulled out after running */
其中 waiters 是一个 Treiber 栈,简单来说,就是由单链表组成的线程安全的栈,如图所示:
- 构造器
// 创建一个 FutureTask 对象,在运行时将执行给定的 Callable
这两个构造器分别传入 Callable 对象和 Runnable 对象(适配为 Callable 对象),然后将其状态初始化为 NEW。
- run: 执行任务
public
- set & setException: 更新状态值,唤醒栈中等待的线程
protected
这两个方法的操作类似,都是更新 state 的值并给返回结果 outcome 赋值,然后执行结束操作 finishCompletion 方法:
private
finishCompletion 方法的作用就是唤醒栈中所有等待的线程,并清空栈。其中的 done 方法实现为空:
protected
子类可以重写该方法实现回调功能。
- get: 获取执行结果
// 获取执行结果(阻塞式)
这两个方法都是获取任务执行的结果,原理也基本一样,区别在于后者有超时等待(超时会抛出 TimeoutException 异常)。
- awaitDone: 等待任务执行完成
// Awaits completion or aborts on interrupt or timeout.
该方法的主要判断步骤如下:
- 若线程被中断,则响应中断;
- 若任务已完成,则返回状态值;
- 若任务正在执行,则让出 CPU 时间片;
- 若任务未执行,则将当前线程封装为 WaitNode 节点;
- 若 WaitNode 未入栈,则执行入栈;
- 若已入栈,则将线程挂起。
以上步骤是循环执行的,其实该方法的主要作用就是:当任务执行完成时,返回状态值;否则将当前线程挂起。
- removeWaiter: 移除栈中的节点
private
- report 方法:封装返回结果
private
该方法就是对返回结果的包装,无论是正常结束或是抛出异常。
- cancel: 取消任务
public
3. 场景举例
FutureTask 适合多线程执行一些耗时的操作,然后获取执行结果。下面结合线程池简单分析其用法,示例代码如下(仅供参考):
public
4. 小结
FutureTask 是一个封装任务(Runnable 或 Callable)的类,可以异步执行任务,并获取执行结果,适用于耗时操作场景。
参考链接:
FutureTask源码分析 - 代码星冰乐www.hchstudio.cn
人类身份验证 - SegmentFaultsegmentfault.comJava的Future机制详解www.jianshu.com
futuretask使用_JDK源码分析-FutureTask相关推荐
- java futuretask 源码解析_Java异步编程——深入源码分析FutureTask
Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...
- JDK源码分析 FutureTask源码分析
文章目录 前言 一.Callable接口 二.Future接口 三.FutureTask源码分析 3.1 Future继承结构图 3.2 参数介绍 3.3 构造函数 3.4. FutureTask的A ...
- 线程池源码分析-FutureTask
1 系列目录 线程池接口分析以及FutureTask设计实现 线程池源码分析-ThreadPoolExecutor 该系列打算从一个最简单的Executor执行器开始一步一步扩展到ThreadPool ...
- c++ vector拷贝构造_JDK源码分析-Vector
1. 概述 上文「JDK源码分析-ArrayList」主要分析了 ArrayList 的实现原理.本文分析 List 接口的另一个实现类:Vector. Vector 的内部实现与 ArrayList ...
- Java并发编程笔记之FutureTask源码分析
FutureTask可用于异步获取执行结果或取消执行任务的场景.通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过Fu ...
- FutureTask源码分析
2019独角兽企业重金招聘Python工程师标准>>> 在JCU中,FutureTask是Future的具体实现,且实现了Runnable接口,即FutureTask满足了Task的 ...
- java futuretask 源码_java并发编程——FutureTask源码分析
FutureTask的简单示例: FutureTask的应用场景,如果在当前线程中需要执行比较耗时的操作,但又不想阻塞当前线程时,可以把这些作业交给FutureTask,另开一个线程在后台完成,当当前 ...
- java实现多线程的方式并源码分析
个人资源与分享网站:首页-小草资源分享网站 方式一:继承Thread 定义一个MyThread类,重写run方法 public class MyThred extends Thread{ @Overr ...
- ExecutorCompletionService 源码分析
概要 在ExecutorService的submit方法中可以获取返回值,通过Future的get方法,但是这个Future类存在缺陷,Future接口调用get()方法取得处理后的返回结果时具有阻塞 ...
最新文章
- 使用Leangoo共享脑图/思维导图做多级需求管理
- 健康饮食动起来[我写绿色IT]
- kubernetes入门指南(一)
- 基础的VueJS面试题(附答案)
- Adobe Acrobat Pro设置高亮快捷键
- Python疑难杂症:SyntaxError: Non-ASCII character Python中文处理问题
- matplotlib绘图进阶
- 破解wifi时遇到rtl8187 - [phy1]SIOCSIFFLAGS: Name not unique on network
- 谷歌浏览器上传下载奔溃问题解决方法
- C++控制输出对齐---setw()函数
- C#实现百度翻译功能
- 网络教育本科统考计算机和英语作文,远程教育本科统考英语真题及答案
- oCPC实践录 | oCPC产品设计与出价原理(1)
- 【Java】——命名规范
- Appium+python(1):python运行真机App程序示例
- 这么多处理器(CPU/SOC)牌子,到底哪家强
- 《满江红》非岳飞所作?
- 数据库的行列互换问题
- 常用SQL语句大全实例总结-基础篇
- 中国数字银行春季论坛热议高质量发展 金融科技破解资产负债管理难题
热门文章
- python使用imbalanced-learn的BorderlineSMOTE方法进行上采样处理数据不平衡问题
- Numpy的广播机制详解(broadcasting)
- java常用注解汇总_Spring常用注解汇总
- LoRDEC:hybrid correction of long reads 长读的混合校正
- 深圳大学计算机暑期学校,The First Day-深度学习暑期学校
- 排班系统c语言设计说明,帮我设计一个关于员工排班的C语言程序
- 五、线程的概念和特点
- Node.js 报语法错误 SyntaxError: Unexpected identifier
- 深度学习:知识回收(Lecture3+4 PLA+Decision Tree)
- gcc8之前,coredump文件无法显示正确的函数调用栈信息