知识点: Java FutureTask 使用详解
FutureTask 使用详解
- 概述
- 类图
- 创建第一个任务
- 取消任务
- 检索结果值
- 总结
概述
FutureTask
可取消的异步任务,提供Future
的基础实现,并实现了Runnable
接口。FutureTask
包含了取消与启动计算的方法,查询计算是否完成以及检索计算结果的方法。只有在计算完成才能检索到结果,调用get()
方法时如果任务还没有完成将会阻塞调用线程至到任务完成。一旦计算完成就不能重新开始与取消计算,但可以调用runAndReset()
重置状态后再重新计算。
类图
FutureTask
实现了RunnableFuture
接口,而RunnableFuture
接口扩展自Future
Runnable
接口,在创建FutureTask
时可以使用Callable
接口的实例或者Lambda表达式,也可以使用Runnable
的实例,但内部还是会使用适配器模式转换成Callable
实例类型。
创建第一个任务
使用Callable
创建一个FutureTask
实例:
FutureTask<Boolean> future = new FutureTask<>(new Callable<Boolean>() {@Overridepublic Boolean call() throws Exception {return true;}});
通过new
一个对象的方法可以直接创建一个FutureTask
实例,如果直接调用run方法将直接在当前线程中运行,不会开启新线程。
使用ExecutorService
或者线程可以让FutureTask
进行托管进行,示例如下:
//托管给线程池处理
Future<?> futureResult = Executors.newCachedThreadPool().submit(future);
//托管给单独线程处理
new Thread(future).start();
因为FutureTask
继承了Runnable
接口,所以它可以通过new Thread()
的方式进行运行,再由future
变量来检索结果值或者取消任务等操作,通过线程池托管的方式也可以适用。
取消任务
遇到特殊情况时需要对没有运行的或者已经运行的任务进行取消操作,这时可以调用cancel()
方法,取消方法有一个布尔类型的参数mayInterruptIfRunning
;当值为ture
时将尝试中断托管的线程(调用托管线程的interrupt
尝试中断)。
取消任务使用的是线程的中断
操作,如果任务是可取消的,在任务中存在阻塞线程的地方需要加上InterruptedException
的异常捕获来处理中断异常或者在任务可取消点使用Thread.currentThread().isInterrupted()
方法来判断任务是否已经发送的中断请求以正常取消任务。
检索结果值
使用FutureTask
的一个重要目的是为了能获取到任务的结果值,使用Callable
使用一个任务调用点时可以在任务中返回一个引用类型。
在FutureTask
内部使用outcome
变量存储Callable
的结果,调用FutureTask.get()
方法将检索结果值,但get()
方法也会阻塞调用线程直到任务执行完成或者取消。
get()
方法还可以通过设置超时时间来指定等待的时长,超过等待时间后将会抛出TimeoutException
异常。
总结
使用FutureTask
可以完成任务的取消、检查结果值,这两项也是FutureTask
的特色,但FutureTask
的底层还是托管给Thread
完成;相对于Thread
检查结果值会更新的方便,不再需要管理线程执行的状态与值。
在使用cancel
方法需要注意任务是否可以取消,在任务内部需要使用Thread.currentThread().isInterrupted()
检查中断状态并在Thread.sleep()
condition.wait()
Thread.join()
Thread.wait()
使用线程进行阻塞以及可中断的I/O操作方法中捕获InterruptedException
异常以避免不必要的情况发生,在大多数任务中是不应该被中断的,所以最好在可中断的任务中设置好检查点;在任务线程会被阻塞点捕获InterruptedException
异常,根据情况判断是否需要取消任务。
赠书活动地址:赠书!《阿里巴巴Java开发手册(第2版)》
精彩推荐:
Java 线程创建的三种方式
Java ClassLoader详解双亲委派的实现原理
Java 反射技术应用与详解
知识点: Java FutureTask 使用详解相关推荐
- java多线程学习-java.util.concurrent详解
http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...
- Java 线程池详解及实例代码
转载自 Java 线程池详解及实例代码 这篇文章主要介绍了Java 线程池的相关资料,并符实例代码,帮助大家学习参考,需要的朋友可以参考下 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时 ...
- 一篇搞定位运算——java位运算详解
java位运算详解 前言 一.位运算符 &:按位与 |:按位或 ~:按位非 ^:按位异或 <<:左位移运算符 >>:右位移运算符 <<<:无符号右移运 ...
- 64位JVM的Java对象头详解
关注"Java艺术"一起来充电吧! 我们编写一个Java类,编译后会生成.class文件,当类加载器将class文件加载到jvm时,会生成一个Klass类型的对象(c++),称为类 ...
- Java多线程进阶详解
文章目录 1.卖票案例引入数据不安全问题 2.同步代码块 深入理解synchronized关键字 3.同步方法与静态同步方法 同步方法 静态同步方法 内置锁 静态同步方法与同步代码块共同使用 为什么要 ...
- Java内存溢出详解之Tomcat配置
Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...
- java基础(十三)-----详解内部类——Java高级开发必须懂的
java基础(十三)-----详解内部类--Java高级开发必须懂的 目录 为什么要使用内部类 内部类基础 静态内部类 成员内部类 成员内部类的对象创建 继承成员内部类 局部内部类 推荐博客 匿名内部 ...
- Java类加载机制详解【java面试题】
Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...
- Java线程池详解学习:ThreadPoolExecutor
Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...
最新文章
- [原] Unity调用android版新浪微博
- 【推荐系统】深入理解推荐系统:排序
- python交互窗口怎么才能不连着上一个程序_python实现启动一个外部程序,并且不阻塞当前进程...
- 十一级指针实现百万qq号的增删查改以及排序写入
- [系统审计]SAP HANA 中的系统审计策略管理
- 避免畸形儿受孕时间有10忌
- Python模拟浏览器向 CSDN发送POST请求的方法
- android碎片实验报告,《Android 移动应用开发》实验报告-范本78(29页)-原创力文档...
- zynq开发系列4:MIO按键中断控制LED
- java泛型为伪泛型,什么,JAVA的泛型是伪泛型
- 【迅雷VIP体验】免费获得迅雷会员,享受高速下载通道
- 微信小程序demo、开发工具下载地址
- 882. Reachable Nodes In Subdivided Graph
- 个人java课设的心得体会收获_java课程设计心得体会
- intel D435i 双目相机 拍摄图片并保存 python调用示例
- C++/openCV修改视频分辨率
- 如何一次性改变word中的数字和字母的字体属性
- 三个常见博弈游戏以及 SG 函数和 SG 定理
- 1小时用马克笔画出时尚女郎
- python之逆解最大公约数与最小公倍数