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类的继承关系如下
    www.wityx.com

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

  • 看看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。

ThreadPoolExecutor是Java用于管理线程池的一个类。它是Executor框架的一种具体实现,提供了对线程池的管理和控制。 以下是ThreadPoolExecutor的简化版源码: ```java public class ThreadPoolExecutor { private final BlockingQueue<Runnable> workQueue; // 任务队列 private final HashSet<Worker> workers; // 工作线程集合 private final ReentrantLock mainLock = new ReentrantLock(); // 控制线程池状态的锁 private final Condition termination = mainLock.newCondition(); // 线程池终止条件 private volatile boolean isShutdown = false; // 线程池是否已关闭 private volatile boolean isTerminating = false; // 线程池是否正在关闭 private volatile boolean isTerminated = false; // 线程池是否已终止 private int corePoolSize; // 核心线程数 private int maximumPoolSize; // 最大线程数 private long keepAliveTime; // 非核心线程的空闲超时时间 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.keepAliveTime = unit.toNanos(keepAliveTime); this.workQueue = workQueue; this.workers = new HashSet<>(); } public void execute(Runnable task) { if (task == null) { throw new NullPointerException(); } if (isShutdown) { throw new RejectedExecutionException(); } int workerCount = workers.size(); if (workerCount < corePoolSize) { // 如果核心线程数未满,直接创建并启动一个核心线程来执行任务 addWorker(task, true); } else if (workQueue.offer(task)) { // 将任务添加到任务队列 // do nothing } else if (workerCount < maximumPoolSize) { // 如果任务队列已满但线程数未达到最大值,则创建并启动一个非核心线程来执行任务 addWorker(task, false); } else { reject(task); // 否则拒绝执行任务 } } private void addWorker(Runnable task, boolean core) { Worker worker = new Worker(task); worker.thread.start(); // 启动工作线程 workers.add(worker); if (core) { corePoolSize++; } } private void reject(Runnable task) { throw new RejectedExecutionException(); } public void shutdown() { mainLock.lock(); try { isShutdown = true; interruptIdleWorkers(); } finally { mainLock.unlock(); } } private void interruptIdleWorkers() { for (Worker worker : workers) { if (!worker.thread.isInterrupted() && worker.tryLock()) { try { worker.thread.interrupt();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值