对比来看java的Runnable&Callable&FutureTask-阿里云开发者社区

开发者社区> 云原生> 正文

对比来看java的Runnable&Callable&FutureTask

简介: 这篇文章其实主要是想要讲清楚一个概念,就是Runable和Callable的区别,以及当它们和FutureTask、ExecutorService一起执行的原理。

这篇文章其实主要是想要讲清楚一个概念,就是Runable和Callable的区别,以及当它们和FutureTask、ExecutorService一起执行的原理。


基本概念

img_074fcd50d5f6a0d71030b4a9d86189ab.png
java多线程实现方案

说明:

    1、上图中java多线程的实现方案就没什么好说的了,基本上搞java的人都是理解的。

    2、其实我始终觉得Thread是一个容器,所以和Runnable和Callable应该不在一个层次的概念,Thread应该是cpu真正调度的实体,这个实体会做什么呢,会执行Runnable和Callable的方法,所以特别不喜欢把这三者放在一起。

基本流程


img_bc646c990274d0b0f40cff11025f5f60.png
FutureTask基本流程

说明:

    1、左边是任务创建过程,右边是任务执行过程。


基本用法

img_921835399eb24ba897d2275f82e47b56.png
常用方法

说明:

    1、这个截图基本上就是Runnable和Callable和ExecutorService结合一起使用的用法。

    2、关键是我比较感兴趣submit内部做了什么事情。


FutureTask创建之Callble对象

img_9ae8912d9e8bdb42e45fdd1827469ea1.png
Callable的futureTask创建过程

说明:

    1、在submit一个对象的时候,其实内部是给我们创建了一个FutureTask对象,整个创建过程是层层递进的。

    2、FutureTask对象有两个重要属性,一个是callable对象也就是执行对象,一个state,标记这个任务是否完成。


FutureTask创建之Runable

img_74fece7d344ffaacc24abd905ecbb257.png
Runnable的FutureTask的创建过程

说明:

    1、当我们针对Runnable对象创建futureTask的时候内部其实用Callable的适配器包装了一下,然后对外以Callable的对象运行。

    2、可以看到call实际上调用的是task的run函数,这个run就不说了吧,线程里面的入口函数。


FutureTask内部属性

img_cb3808fa8725769d7581675c8335b4ee.png
futureTask的核心内容

说明:

    1、几个核心属性,callable就是刚刚所谓的执行对象,outcome最后执行返回的结果,其他整个线程的执行状态流转。


FutureTask任务提交

img_096e57425f274625aafc92d33ae4b67d.png
futureTask提交过程

说明:

    1、这个futureTask的提交过程跟我们跟文章《我发现我不懂你了_JUC》其实是一样的,可以自行参考。

    2、ExecutorService里面的worker其实真正调用的是run函数,所以我们还需要进一步搞清楚FutureTask是否包含run函数,当然毫无疑问肯定是有的,可以参考下面这个图。



FutureTask任务执行

img_b0a9e4be6551c74fab5dfb7ba7d68155.png
futureTask内部实现run接口

说明:

    1、接上面描述的文字,所以ExecutorService的worker其实真正执行的是Callable对象的call函数并设置回调结果。

版权声明:本文首发在云栖社区,遵循云栖社区版权声明:本文内容由互联网用户自发贡献,版权归用户作者所有,云栖社区不为本文内容承担相关法律责任。云栖社区已升级为阿里云开发者社区。如果您发现本文中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,阿里云开发者社区将协助删除涉嫌侵权内容。

分享:
云原生
使用钉钉扫一扫加入圈子
+ 订阅

云原生时代,是开发者最好的时代

其他文章