ThreadPoolExecutor源码中的适配器模式
什么是适配器模式
网上已有很多的教程,不细讲了。可以参考:五分钟了解设计模式(3)---适配器模式
在适配器模式中,一定要识别清楚,Target Adaptee Adapter分别是哪些类或接口,这样才能知道是谁转成谁。
Target: 最终给上下文调用的类
Adaptee: 被适配的类,即需要转成Target
Adapter: 将Target和Adaptee连接起来,起转换作用
ThreadPoolExecutor中submit方法用到的适配器模式
ThreadPoolExecutor类提供了submit方法,共有3个重载。这三个方法最终调用到的是execute(Runnable r) 方法,返回一个Future类型的对象(具体为FutureTask类型),相比直接调用execute(Runnable r)方法,调用方可以获得任务执行的结果。三个submit方法, 都使用了适配器模式,才能将顺利调用execute(Runnable r)方法。
- 先看看public Future submit(Callable task)
在这个方法中,Target是Runnable(因为execute方法的参数是Runnable类型),Adaptee是Callable。JDK使用了FutureTask类作为Adapter. FutureTask类的继承关系如下

实现了Runnable,可以传参给execute方法;实现了Future,可以返回给调用方。
FutureTask作为Adapter,采用的是“类适配器方式”,持有一个Callable(即Adaptee)。

再看看public Future submit(Runnable task, T result)
同样是包装成FutureTask类型,那么只要将Runnable转成FutureTask就可以了。上面说到FutureTask也是实现了Runnable,那为什么还要转换呢?因为FutureTask还实现了Future接口,功能上比Runnable更强大,同时要返回给调用方,提供运行结果。
当前我们有一个Runnable和表示结果的参数,需要适配成FutureTask。前面我们已经知道,FutureTask起到Adapter的作用,它持有一个Callable成员变量。如果没有上面的分析,那么FutureTask可以改为持有Runnable,但现在它已经是持有Callable成员变量了,所以,还要再做一次适配,将Runnable适配成Callable.
在这个例子中,Target是Callable,Adaptee是Runnable,Adapter是RunnableAdapter。
RunnableAdapter使用“类适配器方式”

最后一个public Future<?> submit(Runnable task)
与上一个方法类似,只不过是运行结果为null.
总结
在ThreadPoolExecutor的三个submit方法中,都使用了适配器模式,都使用了其中的“类适配器方式”。
submit方法都返回FutureTask,该类型可以得到运行结果。
submit方法都调用了execute(Runnable r)方法执行任务,传入的具体类型为FutureTask。因此,Target是Runnable,Adapter是FutureTask,Adaptee则是不同的传入参数。
FutureTask的实现方式是持有一个Callable类型的成员变量,因此,对于传入参数为Callable的情况,直接赋值,对于传入参数为Runnable的情况,需要再做一次适配,将Runnable适配成Callable. 在这个转换过程中,Target是Callable,Adaptee是Runnable,Adapter是Adapter是RunnableAdapter。
ThreadPoolExecutor源码中的适配器模式的更多相关文章
- MMS源码中异步处理简析
1,信息数据的查询,删除使用AsycnQueryHandler处理 AsycnQueryHandler继承了Handler public abstract class AsyncQueryHandle ...
- Java并发包源码学习之线程池(一)ThreadPoolExecutor源码分析
Java中使用线程池技术一般都是使用Executors这个工厂类,它提供了非常简单方法来创建各种类型的线程池: public static ExecutorService newFixedThread ...
- ThreadPoolExecutor系列<三、ThreadPoolExecutor 源码解析>
本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681826.html 在源码解析前,需要先理清线程池控制的运行状态 ...
- 线程池ThreadPoolExecutor源码解读研究(JDK1.8)
一.什么是线程池 为什么要使用线程池?在多线程并发开发中,线程的数量较多,且每个线程执行一定的时间后就结束了,下一个线程任务到来还需要重新创建线程,这样线程数量特别庞大的时候,频繁的创建线程和销毁线程 ...
- Android 源码中的设计模式
最近看了一些android的源码,发现设计模式无处不在啊!感觉有点乱,于是决定要把设计模式好好梳理一下,于是有了这篇文章. 面向对象的六大原则 单一职责原则 所谓职责是指类变化的原因.如果一个类有多于 ...
- ThreadPoolExecutor系列三——ThreadPoolExecutor 源码解析
ThreadPoolExecutor 源码解析 本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681826.htm ...
- ThreadPoolExecutor源码解析(二)
1.ThreadPoolExcuter运行实例 首先我们先看如何新建一个ThreadPoolExecutor去运行线程.然后深入到源码中去看ThreadPoolExecutor里面使如何运作的. pu ...
- 【Java并发编程】21、线程池ThreadPoolExecutor源码解析
一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...
- ThreadPoolExecutor源码解读
1. 背景与简介 在Java中异步任务的处理,我们通常会使用Executor框架,而ThreadPoolExecutor是JUC为我们提供的线程池实现. 线程池的优点在于规避线程的频繁创建,对线程资源 ...
随机推荐
- Spring MVC-从零开始-@RequestMapping 注解value属性
1.@RequestMapping 注解可以在控制器类的级别和/或其中的方法的级别上使用. 2.直接在方法上使用@RequestMapping package com.jt; import org.s ...
- java 队列和栈及示例
一.栈的实现: 1.Stack实现 接口实现: class Stack<E> extends Vector<E> {......} 常用的api函数如下: boolean is ...
- angular6 iframe应用
问题一. iframe如何自适应屏幕高度 解决思路:通过设置iframe外层父元素高度等于window高度,再相对于父元素定位iframe元素:案例如下: 第一步: 模板文件中使用iframe // ...
- 两小无猜的爱恨情仇--java =+和+=揭秘
故事背景 当一个人问另一个人“敢不敢”的时候,另一个人必须说“敢”,这就是游戏的规则.小男孩朱利安和小女孩苏菲的相遇即开始于这样一场孩童的闹剧,一个精美的铁盒子就是他们游戏的见证.说脏话,扰乱课堂,在 ...
- SpringBoot返回JSON
目录 1.SpringBoot返回JSON简介 2.整合jackson-databind 3.整合Gson 4.整合fastjson 1.SpringBoot返回JSON简介 随着web开发前后端分离 ...
- 游戏服务器和Web服务器的区别
用Go语言写游戏服务器也有一个多月了,也能够明显的感受到两者的区别.这篇文章就是想具体的聊聊其中的区别.当然,在了解区别之间,我们先简单的了解一下Go语言本身. 1. Go语言的特点 Go语言跟其他的 ...
- KafkaStream简介
Kafka Streams 1 概述 Kafka Streams是一个客户端程序库,用于处理和分析存储在Kafka中的数据,并将得到的数据写回Kafka或发送到外部系统.Kafka Stream基于一 ...
- nginx的负载均衡实战
前言 nginx是一个高性能的HTTP和反向代理的服务器.它有三个最基本的功能,一是当做web服务器.二是作为反向代理服务器.三是提供负载均衡(在反向代理基础上),由于它占有内存小,并发能力强,所以在 ...
- 各种常见文件的hex文件头
我们在做ctf时,经常需要辨认各种文件头,跟大家分享一下一些常见的文件头. 扩展名 文件头标识(HEX) 文件描述 123 00 00 1A 00 05 10 04 Lotus 1-2-3 spr ...
- Kotlin 中的伴生对象和静态成员
用了一段时间kotlin,越用越觉得好用,爱不释手啊,留点笔记. Kotlin 中,在类中定义的对象(object)声明,可使用 companion 修饰,这样此对象(object)就是伴生对象了.类 ...