文章目录
一、线程池 reject 拒绝任务
二、线程池 addWorker 添加任务
在上一篇博客 【Android 异步操作】线程池 ( 线程池 execute 方法源码解析 ) 中 , 讲解 线程池 ThreadPoolExecutor 的 execute 方法时 , 有两个重要的核心方法 ;
两个核心的操作 :
添加任务 : addWorker(command, true) , 第二个参数为 true 是添加核心线程任务 , 第二个参数为 false 是添加非核心线程任务 ;
拒绝任务 : reject(command)
本博客中研究 拒绝任务 reject 方法的细节 ;
一、线程池 reject 拒绝任务
在 ThreadPoolExecutor 线程池中 , void reject(Runnable command) 方法 , 主要是调用了 RejectedExecutionHandler handler 的 rejectedExecution 方法 ;
该 handler 可以在如下 构造函数中传入 , 如下构造函数中的最后一个参数 ;
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
部分相关代码示例 :
public class ThreadPoolExecutor extends AbstractExecutorService { /** * 当线程池任务饱和 , 或线程池关闭 , 使用该 Handler 处理拒绝任务异常情况 ; */ private volatile RejectedExecutionHandler handler; /** * 在该构造函数中 , 可以传入 Handler ; */ public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; } /** * 拒绝执行给定命令的处理 */ final void reject(Runnable command) { handler.rejectedExecution(command, this); } }
自定义 RejectedExecutionHandler 处理拒绝任务的情况 ;
实现 rejectedExecution 方法 , 当 线程池任务队列饱和 , 或者 没有空闲线程 时 , 线程池被关闭 时 , 导致线程池的任务队列无法接受该任务时 , 会调用该方法
/** * 处理添加任务失败情况的 handler * 用户可以自定义该接口 */ public interface RejectedExecutionHandler { /** * * 无法接受任务时执行该方法 ; * 当线程池任务队列饱和 , 或者没有空闲线程时 , 线程池被关闭时 , 会调用该方法 * * 该方法可能会触发 RejectedExecutionException 异常 , 用户需要捕获并处理该异常 * * @param r 被拒绝的任务 * @param executor 尝试执行该任务的执行者 * @throws RejectedExecutionException 如果没有补救方法, 抛出该异常 */ void rejectedExecution(Runnable r, ThreadPoolExecutor executor); }
二、线程池 addWorker 添加任务
检查一个新的工作者 ( Worker ) 是否可以被添加 , 根据当前的 线程池状态 , 和 给定的核心线程数 , 最大线程数 等判定 ;
如果可以添加 , 那么先 调整 工作者 ( Worker ) 的个数 , 然后 创建新的 工作者 ( Worker ) , 并 将参数中的 Runnable firstTask 设置为第一个任务 ;
如果线程池停止或关闭 , 返回 false ;
如果线程创建失败 , 不管是线程工厂返回空 , 还是出现 OOM , 直接退出 ;
如果当前的 线程个数少于 核心线程数 , 或者当前的 任务数已满 , 则必须创建 工作者 ( Worker ) , 并执行第一个初始任务 ,
public class ThreadPoolExecutor extends AbstractExecutorService { /** * 检查一个新的工作者是否可以被添加 , 根据当前的线程池状态 , 和给定的核心线程数 , 最大线程数等判定 ; * 如果可以添加 , 那么先调整 工作者 ( Worker ) 的个数 , 然后创建新的 工作者 ( Worker ) , * 并将参数中的 Runnable firstTask 设置为第一个任务 ; * 如果线程池停止或关闭 , 返回 false ; * 如果线程创建失败 , 不管是线程工厂返回空 , 还是出现 OOM , 直接退出 ; * * 第一个运行的任务 ; * 如果当前的线程个数少于 核心线程数 , 或者当前的任务数已满 , * 必须创建 工作者 ( Worker ) , 并执行第一个初始任务 , * * @param core 如果设置为 true , 必须使用核心线程绑定 * @return true if successful */ private boolean addWorker(Runnable firstTask, boolean core) { retry: // 死循环 for (;;) { int c = ctl.get(); int rs = runStateOf(c); // 查看队列是否为空 // 查看线程池是否 SHUTDOWN if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; // 查看线程池的线程个数 , 与 核心线程数, 最大线程数 进行各种对比 // 获取现在的线程池情况 for (;;) { int wc = workerCountOf(c); if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; // 如果没有达到最大线程数 , 允许添加 if (compareAndIncrementWorkerCount(c)) // 该行代码只是将计数器 +1 break retry; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } } // 下面是添加一个线程的逻辑 boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { // 创建工作者 , 并将任务设置给该工作者 w = new Worker(firstTask); // 线程是从工作者中取出的 , 该线程是在 Worker 构造函数中使用线程工厂创建的 final Thread t = w.thread; if (t != null) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int rs = runStateOf(ctl.get()); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); // 将工作者设置给 工作者集合 workers.add(w); int s = workers.size(); if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } // 如果添加成功 , 就会启动 Worker 中的线程 if (workerAdded) { t.start(); workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; } }