欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > Android >内容正文

Android

【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 )

发布时间:2025/6/17 Android 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 ) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

文章目录

  • 一、线程池 reject 拒绝任务
  • 二、线程池 addWorker 添加任务



在上一篇博客 【Android 异步操作】线程池 ( 线程池 execute 方法源码解析 ) 中 , 讲解 线程池 ThreadPoolExecutorexecute 方法时 , 有两个重要的核心方法 ;

两个核心的操作 :

  • 添加任务 : addWorker(command, true) , 第二个参数为 true 是添加核心线程任务 , 第二个参数为 false 是添加非核心线程任务 ;
  • 拒绝任务 : reject(command)

本博客中研究 拒绝任务 reject 方法的细节 ;





一、线程池 reject 拒绝任务



ThreadPoolExecutor 线程池中 , void reject(Runnable command) 方法 , 主要是调用了 RejectedExecutionHandler handlerrejectedExecution 方法 ;

该 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)) // 该行代码只是将计数器 +1break retry;c = ctl.get(); // Re-read ctlif (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 startablethrow 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;} }

总结

以上是生活随笔为你收集整理的【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 )的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。