Callable和Future接口的实现
一、Callable和Future
Callable接口定义了一个call方法可以作为线程的执行体,但call方法比run方法更强大:
- call方法可以有返回值
- call方法可以申明抛出异常
- Callable接口是JDK5后新增的接口,而且不是Runnable的子接口,所以Callable对象不能直接作为Thread的target。
- call方法还有一个返回值,call方法不能直接调用,它作为线程的执行体被调用。
- 那么如何接收call方法的返回值?
JDK1.5提供了Future接口来代表Callable接口里的call方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现Future接口,并实现了Runnable接口—可以作为Thread的target。
二、Future接口里定义了如下几个公共方法控制他关联的Callable任务
- boolean cancel(Boolean mayInterruptlfRunning):试图取消该Future里关联的Callable任务
- V get():返回Callable任务里的call方法的返回值,调用该方法将导致线程阻塞,必须等到子线程结束才得到返回值
- V get(long timeout, TimeUnit unit):返回Callable任务里的call方法的返回值,该方法让程序最多阻塞timeout和unit指定的时间。如果经过指定时间后Callable任务依然没有返回值,将会抛出TimeoutException。
- boolean isCancelled:如果在Callable任务正常完成前被取消,则返回true。
- boolean isDone:如果Callable任务已经完成,则返回true
三、创建、并启动有返回值的线程的步骤如下
- 创建Callable接口的实现类,并实现call方法,该call方法的返回值,并作为线程的执行体。
- 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值
- 使用FutureTask对象作为Thread对象的target创建、并启动新线程
- 调用FutureTask对象的方法来获得子线程执行结束后的返回值
四、总结
Executor框架使用Runnable作为其任务的基本表达形式。Runnable相当有限,不能返回一个值,也不能抛出受检查的异常,对于复杂费时的计算更加无法处理
因此产生了Callable和Future这种任务,对任务进行全面管理
Callable在主进入点-call处等待返回值,并为可能抛出的异常预先做了准备。
Executors包含了一些工具方法将其他类型的任务封装成一个Callable,比如Runnable和java.security.PrivilegedAction。Runnable和Callable描述的是抽象的计算型任务。
这些任务很有限,有明确的开始和结束,但是对于非常费时的任务比较麻烦,对于已经提交但尚未开始的任务可以取消,但是对于已经开始的任务,只有它们响应中断,才可以取消。
Future描述了任务的生命周期,并提供了相关的方法来获得任务的结果、取消任务以及检验任务已经完成还是被取消。
Future意味着任务完成后永远停留在完成状态上,就像ExecutorService的生命周期。使用get方法完成任务和异常处理。
ExecutorService中的所有submit方法都返回一个Future,可以将一个Runnable或一个Callable提交给executor,然后得到一个Future。也可以显式地为给定的Runnable或Callable实例化一个FutureTask。
五、例子
public class CallableInterface {@Testpublic void testCall() throws InterruptedException, ExecutionException {//callable无法直接放到Thread中,而Runnable而已,能否将callable与Runnable扯上关系?就是FutureTask类//FutureTask构造可以传递Callable,同时也是Runnable的实现类//FutureTask使用场景:// 1.在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。// 2.一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。// 3.仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。// get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。// 4.只计算一次,get方法放到最后,可以使用isDone方法,判断是否计算完,再获取//常规代码//FutureTask<Integer> futureTask=new FutureTask<>(new RealizeCallable());//lambda//一般FutureTask多用于耗时的计算,如果计算尚未完成,则阻塞 get 方法。// 只计算一次,get方法放到最后,可以使用isDone方法,判断是否计算完,再获取。// 复杂的任务,多开几个线程计算,分支合并。FutureTask<Integer> futureTask1=new FutureTask<>(()-> {System.out.println(Thread.currentThread().getName()+" come in callable");int a=0;for (int i = 0; i < 1000; i++) {a+=i;}return a;});FutureTask<Integer> futureTask2=new FutureTask<>(()-> {System.out.println(Thread.currentThread().getName()+ " come in callable");int a=0;for (int i = 0; i < 20000; i++) {a+=i;}return a;});//创建一个线程Thread thread1=new Thread(futureTask1,"futureTask1");Thread thread2=new Thread(futureTask2,"futureTask2");thread1.start();thread2.start();while (!futureTask1.isDone()){System.out.println("futureTask1 waiting......");}while (!futureTask2.isDone()){System.out.println("futureTask2 waiting......");}System.out.println("futureTask1 result is " +futureTask1.get());System.out.println("futureTask2 result is " +futureTask2.get());System.out.println(Thread.currentThread().getName()+"over");thread1.join();thread2.join();}
}
参考文章
Callable和Future接口的实现相关推荐
- Java并发编程-Executor框架之Callable和Future接口
在上一篇文章中我们已经了解了Executor框架进行线程管理,这篇文章将学习Executor框架的另一个特性,我们知道执行Runnable任务是没有返回值得,但Executor可以运行并发任务并获得返 ...
- Callable 和 Future接口 学习
* Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务. * Callable和Runnable有几点不同: * (1)C ...
- JUC系列(六) | Callable和Future接口详解使用、FutureTask应用 获取异步线程返回值
多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...
- 使用Callable和Future接口创建线程
https://www.cnblogs.com/ganchuanpu/p/7704468.html
- Callable与Future的简单介绍
Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...
- Callable与Future的介绍
Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...
- 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )
文章目录 一.Future 接口 1.Future 接口简介 2.取消任务方法 3.Future 接口源码注释 二.Callable 接口 三.Runnable 接口 上一篇博客 [Android 异 ...
- Callable接口、Runable接口、Future接口
转自:https://www.cnblogs.com/felixzh/p/6044371.html 参考:https://blog.csdn.net/qq_36761831/article/detai ...
- 一次搞懂 Runnable、Callable、Future、FutureTask,不懂不要钱!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 一般创建线程只有两种方式,一种是继承Thread,一种是实 ...
最新文章
- Android Camera 通过V4L2与kernel driver的完整交互过程
- csu 1548: Design road (三分)
- 数据挖掘学习日志(part1)--熵值法
- linux kafka离线安装,centos 离线安装confluent_kafka 模块
- vue标准时间改为时间戳_正确的济南初中寒假放假时间安排出来啦!家长速戳→...
- linux httpd 内存,apache占用内存过高耗完内存?
- 拷贝data/data/包名/files文件记下所有文件及文件夹到本地sdcard根目录teddyData_files文件夹下...
- 红外通信红外编码—NEC协议
- 设置linux开机自动运行某条命令或程序和安装jdk(jar)
- git clone报错Could not resolve proxy : proxy-szn
- 机器学习中的F1-score
- 854计算机基础——备考建议+近年考点汇总
- 如何使用python在一个图片内显示多个函数图像及其数学公式
- Linux: fPIC与 pie 区别
- 关于自己的一些想法-网络通用消费返点平台
- android 购物车操作并发,Android 购物车页面和逻辑实现
- android浪漫樱花凋零动态壁纸应用源码
- 信息系统建设和服务能力评估CS认证知识讲解
- 基于matlab的循环卷积,【 MATLAB 】【 MATLAB 】DFT的性质讨论(三)序列的循环卷积及其 MATLAB 实现...
- Ehcache 中ehcache.xml 配置详解和示例