一、Callable和Future

Callable接口定义了一个call方法可以作为线程的执行体,但call方法比run方法更强大:

  1. call方法可以有返回值
  2. call方法可以申明抛出异常
  1. Callable接口是JDK5后新增的接口,而且不是Runnable的子接口,所以Callable对象不能直接作为Thread的target。
  2. call方法还有一个返回值,call方法不能直接调用,它作为线程的执行体被调用。
  3. 那么如何接收call方法的返回值?
    JDK1.5提供了Future接口来代表Callable接口里的call方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现Future接口,并实现了Runnable接口—可以作为Thread的target。

二、Future接口里定义了如下几个公共方法控制他关联的Callable任务

  1. boolean cancel(Boolean mayInterruptlfRunning):试图取消该Future里关联的Callable任务
  2. V get():返回Callable任务里的call方法的返回值,调用该方法将导致线程阻塞,必须等到子线程结束才得到返回值
  3. V get(long timeout, TimeUnit unit):返回Callable任务里的call方法的返回值,该方法让程序最多阻塞timeout和unit指定的时间。如果经过指定时间后Callable任务依然没有返回值,将会抛出TimeoutException。
  4. boolean isCancelled:如果在Callable任务正常完成前被取消,则返回true。
  5. boolean isDone:如果Callable任务已经完成,则返回true

三、创建、并启动有返回值的线程的步骤如下

  1. 创建Callable接口的实现类,并实现call方法,该call方法的返回值,并作为线程的执行体。
  2. 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值
  3. 使用FutureTask对象作为Thread对象的target创建、并启动新线程
  4. 调用FutureTask对象的方法来获得子线程执行结束后的返回值

四、总结

  1. Executor框架使用Runnable作为其任务的基本表达形式。Runnable相当有限,不能返回一个值,也不能抛出受检查的异常,对于复杂费时的计算更加无法处理

  2. 因此产生了Callable和Future这种任务,对任务进行全面管理

  1. Callable在主进入点-call处等待返回值,并为可能抛出的异常预先做了准备。

  2. Executors包含了一些工具方法将其他类型的任务封装成一个Callable,比如Runnable和java.security.PrivilegedAction。Runnable和Callable描述的是抽象的计算型任务。

  3. 这些任务很有限,有明确的开始和结束,但是对于非常费时的任务比较麻烦,对于已经提交但尚未开始的任务可以取消,但是对于已经开始的任务,只有它们响应中断,才可以取消。

  1. Future描述了任务的生命周期,并提供了相关的方法来获得任务的结果、取消任务以及检验任务已经完成还是被取消。

  2. Future意味着任务完成后永远停留在完成状态上,就像ExecutorService的生命周期。使用get方法完成任务和异常处理。

  3. 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接口的实现相关推荐

  1. Java并发编程-Executor框架之Callable和Future接口

    在上一篇文章中我们已经了解了Executor框架进行线程管理,这篇文章将学习Executor框架的另一个特性,我们知道执行Runnable任务是没有返回值得,但Executor可以运行并发任务并获得返 ...

  2. Callable 和 Future接口 学习

    * Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务. * Callable和Runnable有几点不同: * (1)C ...

  3. JUC系列(六) | Callable和Future接口详解使用、FutureTask应用 获取异步线程返回值

    多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...

  4. 使用Callable和Future接口创建线程

    https://www.cnblogs.com/ganchuanpu/p/7704468.html

  5. Callable与Future的简单介绍

    Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...

  6. Callable与Future的介绍

    Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...

  7. 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )

    文章目录 一.Future 接口 1.Future 接口简介 2.取消任务方法 3.Future 接口源码注释 二.Callable 接口 三.Runnable 接口 上一篇博客 [Android 异 ...

  8. Callable接口、Runable接口、Future接口

    转自:https://www.cnblogs.com/felixzh/p/6044371.html 参考:https://blog.csdn.net/qq_36761831/article/detai ...

  9. 一次搞懂 Runnable、Callable、Future、FutureTask,不懂不要钱!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 一般创建线程只有两种方式,一种是继承Thread,一种是实 ...

最新文章

  1. Android Camera 通过V4L2与kernel driver的完整交互过程
  2. csu 1548: Design road (三分)
  3. 数据挖掘学习日志(part1)--熵值法
  4. linux kafka离线安装,centos 离线安装confluent_kafka 模块
  5. vue标准时间改为时间戳_正确的济南初中寒假放假时间安排出来啦!家长速戳→...
  6. linux httpd 内存,apache占用内存过高耗完内存?
  7. 拷贝data/data/包名/files文件记下所有文件及文件夹到本地sdcard根目录teddyData_files文件夹下...
  8. 红外通信红外编码—NEC协议
  9. 设置linux开机自动运行某条命令或程序和安装jdk(jar)
  10. git clone报错Could not resolve proxy : proxy-szn
  11. 机器学习中的F1-score
  12. 854计算机基础——备考建议+近年考点汇总
  13. 如何使用python在一个图片内显示多个函数图像及其数学公式
  14. Linux: fPIC与 pie 区别
  15. 关于自己的一些想法-网络通用消费返点平台
  16. android 购物车操作并发,Android 购物车页面和逻辑实现
  17. android浪漫樱花凋零动态壁纸应用源码
  18. 信息系统建设和服务能力评估CS认证知识讲解
  19. 基于matlab的循环卷积,【 MATLAB 】【 MATLAB 】DFT的性质讨论(三)序列的循环卷积及其 MATLAB 实现...
  20. Ehcache 中ehcache.xml 配置详解和示例

热门文章

  1. python中类中属性和方法的具体定义方法和使用
  2. cdh版本的sqoop安装以及配置
  3. eclipse 模版的使用
  4. 2016.6.23 随笔———— AJAX
  5. 第五节 面向对象相关特性
  6. C++ Primer 第10章 习题 10.18
  7. Asp.net高级程序设计之服务器控件(4)
  8. 统计学习:方差分析(ANOVA2)
  9. Linux下远程连接断开后如何让程序继续运行
  10. 大数问题(一个特别大的数需要用数组或字符串来表示)