线程之Callable、Future 和FutureTask使用及源码分析
一、Callable
我们知道启动线程有以下两种方式(jdk源码注释中官方定义只有两种启动方式,callable不算线程启动方式) 原文链接:http://www.studyshare.cn/blog/details/1141/1
(1)、new Thread().start()
(2)、new Thread(new Runnable()).start();
以上两种方式中的run()方法的返回值是void类型,即没有返回值,如果我们需要在业务线程中执行业务代码后需要将结果进行返回怎么办呢?即使用Callable,如下:
![](https://upload-images.jianshu.io/upload_images/14253062-dd140988a3ed9fda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
java开发工具下载地址及安装教程大全,点这里。
更多技术文章,在这里。
二、调用方式
当使用Callable定义后如何调用,我们发现Thread类并没有接收Callable参数的构造方法,只有接收Runnable接口参数的构造方法,此时我们需要用到一个包装类FutrueTask将Callable进行包装,包装成Runnable,然后传递给Thread的构造方法即可。
![](https://upload-images.jianshu.io/upload_images/14253062-716e5bf7e4ed6cdc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
运行后结果输出:1
三、FutrueTask与Future源码分析
1、FutrueTask类实现了RunnableFutrue接口,如下图
![](https://upload-images.jianshu.io/upload_images/14253062-c3937a959848747d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2、RunnableFutrue接口继承了Runnable和Futrue接口,如下图
![](https://upload-images.jianshu.io/upload_images/14253062-f903557b4ec537c2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
由上图即可发现,FutrueTask类间接的实现了Runnable接口,从而可以使用new Thread(new FutrueTask(callable))去调用线程的start()方法启动线程。
3、继续进入Future接口中会发现get()方法
![](https://upload-images.jianshu.io/upload_images/14253062-0a27e0fa4d3c4221.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
因此FutrueTask可以通过调用get()方法获取到返回的结果。用一张图来总结以上几个类和接口之间的关系,如下图:
![](https://upload-images.jianshu.io/upload_images/14253062-1caa8157159d8869.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)