对比来看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函数并设置回调结果。

目录
相关文章
|
27天前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
|
30天前
|
存储 安全 Java
深入理解Java中的FutureTask:用法和原理
【10月更文挑战第28天】`FutureTask` 是 Java 中 `java.util.concurrent` 包下的一个类,实现了 `RunnableFuture` 接口,支持异步计算和结果获取。它可以作为 `Runnable` 被线程执行,同时通过 `Future` 接口获取计算结果。`FutureTask` 可以基于 `Callable` 或 `Runnable` 创建,常用于多线程环境中执行耗时任务,避免阻塞主线程。任务结果可通过 `get` 方法获取,支持阻塞和非阻塞方式。内部使用 AQS 实现同步机制,确保线程安全。
|
30天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
20 3
|
30天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
37 2
|
30天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
30 2
|
30天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
34 1
|
2月前
|
Java
JAVA并发编程系列(13)Future、FutureTask异步小王子
本文详细解析了Future及其相关类FutureTask的工作原理与应用场景。首先介绍了Future的基本概念和接口方法,强调其异步计算特性。接着通过FutureTask实现了一个模拟外卖订单处理的示例,展示了如何并发查询外卖信息并汇总结果。最后深入分析了FutureTask的源码,包括其内部状态转换机制及关键方法的实现原理。通过本文,读者可以全面理解Future在并发编程中的作用及其实现细节。
|
3月前
|
Java
在 Java 中 Runnable 与 Thread 的适时运用
【8月更文挑战第22天】
25 0
|
Java
Java多线程02—实现Runnable接口的方式创建线程
Java多线程02—实现Runnable接口的方式创建线程
121 0
下一篇
无影云桌面