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是RunnableAdapter。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现