什么是适配器模式

网上已有很多的教程,不细讲了。可以参考:五分钟了解设计模式(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源码中的适配器模式的更多相关文章

  1. MMS源码中异步处理简析

    1,信息数据的查询,删除使用AsycnQueryHandler处理 AsycnQueryHandler继承了Handler public abstract class AsyncQueryHandle ...

  2. Java并发包源码学习之线程池(一)ThreadPoolExecutor源码分析

    Java中使用线程池技术一般都是使用Executors这个工厂类,它提供了非常简单方法来创建各种类型的线程池: public static ExecutorService newFixedThread ...

  3. ThreadPoolExecutor系列<三、ThreadPoolExecutor 源码解析>

    本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681826.html 在源码解析前,需要先理清线程池控制的运行状态 ...

  4. 线程池ThreadPoolExecutor源码解读研究(JDK1.8)

    一.什么是线程池 为什么要使用线程池?在多线程并发开发中,线程的数量较多,且每个线程执行一定的时间后就结束了,下一个线程任务到来还需要重新创建线程,这样线程数量特别庞大的时候,频繁的创建线程和销毁线程 ...

  5. Android 源码中的设计模式

    最近看了一些android的源码,发现设计模式无处不在啊!感觉有点乱,于是决定要把设计模式好好梳理一下,于是有了这篇文章. 面向对象的六大原则 单一职责原则 所谓职责是指类变化的原因.如果一个类有多于 ...

  6. ThreadPoolExecutor系列三——ThreadPoolExecutor 源码解析

    ThreadPoolExecutor 源码解析 本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681826.htm ...

  7. ThreadPoolExecutor源码解析(二)

    1.ThreadPoolExcuter运行实例 首先我们先看如何新建一个ThreadPoolExecutor去运行线程.然后深入到源码中去看ThreadPoolExecutor里面使如何运作的. pu ...

  8. 【Java并发编程】21、线程池ThreadPoolExecutor源码解析

    一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了 ...

  9. ThreadPoolExecutor源码解读

    1. 背景与简介 在Java中异步任务的处理,我们通常会使用Executor框架,而ThreadPoolExecutor是JUC为我们提供的线程池实现. 线程池的优点在于规避线程的频繁创建,对线程资源 ...

随机推荐

  1. Hive窗口函数最全案例详解

    语法: 分析函数 over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置) 常用分析函数: 聚合类 avg().sum().max(). ...

  2. 基于windows的Redis后台服务安装卸载管理

    首先,需要你进入你的Redis解压根目录,例如,类似于我下图的这样子: 接着打开你的cmd,使用cd命令切换到该目录,或者直接在上图的地址栏输入“cmd”并回车.这里为什么让你先使用资源管理器找到你的 ...

  3. Spring boot 官网学习笔记 - Spring Boot CLI 入门案例

    安装CLI https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.1.1.RELEASE/spring-b ...

  4. 前端使用lodop插件进行打印设置

    先前梳理了后台打印导出参考:https://www.cnblogs.com/yyk1226/p/9856032.html,但是没有显示出来打印预览页面. 本章使用Lodop插件进行打印设置,实现打印机 ...

  5. pikachu-数字型注入(post)#手工注入

    1, 因为是post型,所以需要抓取数据包 2, 测试结果为数字型注入 提交恒等的语句可以查询到所有的数据信息 3, 使用UNION联合查询法 判断字段数,测试为2个字段时没有报错,所以可以判断字段数 ...

  6. bootstrap准备工作(1)

    1.下载bootstrap包 http://v3.bootcss.com/getting-started/#download 2.下载结构 如果要用js里面的js效果,需要先插入juqery.js & ...

  7. 【linux】jdk安装及环境变量配置

    登录linux后,切换目录到 /usr/local cd /user/local 在/usr/local目录新建文件夹java用于存放jdk文件 mkdir java 在文件夹java中下载jdk文件 ...

  8. 设置Activity全屏的方法:

    1)代码隐藏ActionBar 在Activity的onCreate方法中调用getActionBar.hide();即可 2)通过requestWindowFeature设置 requestWind ...

  9. 文件/大文件上传功能实现(JS+PHP)全过程

    文件/大文件上传功能实现(JS+PHP) 参考博文:掘金-橙红年代 前端大文件上传 路漫漫 其修远 PHP + JS 实现大文件分割上传 本文是学习文件上传后的学习总结文章,从无到有实现文件上传功能, ...

  10. 从单片机到操作系统⑦——深入了解FreeRTOS的延时机制

    >没研究过操作系统的源码都不算学过操作系统 # FreeRTOS 时间管理 时间管理包括两个方面:系统节拍以及任务延时管理. ## 系统节拍: 在前面的文章也讲得很多,想要系统正常运行,那么时钟 ...