【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 )
文章目錄
- 一、線程池 reject 拒絕任務(wù)
- 二、線程池 addWorker 添加任務(wù)
在上一篇博客 【Android 異步操作】線程池 ( 線程池 execute 方法源碼解析 ) 中 , 講解 線程池 ThreadPoolExecutor 的 execute 方法時(shí) , 有兩個(gè)重要的核心方法 ;
兩個(gè)核心的操作 :
- 添加任務(wù) : addWorker(command, true) , 第二個(gè)參數(shù)為 true 是添加核心線程任務(wù) , 第二個(gè)參數(shù)為 false 是添加非核心線程任務(wù) ;
- 拒絕任務(wù) : reject(command)
本博客中研究 拒絕任務(wù) reject 方法的細(xì)節(jié) ;
一、線程池 reject 拒絕任務(wù)
在 ThreadPoolExecutor 線程池中 , void reject(Runnable command) 方法 , 主要是調(diào)用了 RejectedExecutionHandler handler 的 rejectedExecution 方法 ;
該 handler 可以在如下 構(gòu)造函數(shù)中傳入 , 如下構(gòu)造函數(shù)中的最后一個(gè)參數(shù) ;
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {部分相關(guān)代碼示例 :
public class ThreadPoolExecutor extends AbstractExecutorService {/*** 當(dāng)線程池任務(wù)飽和 , 或線程池關(guān)閉 , 使用該 Handler 處理拒絕任務(wù)異常情況 ;*/private volatile RejectedExecutionHandler handler;/*** 在該構(gòu)造函數(shù)中 , 可以傳入 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;}/*** 拒絕執(zhí)行給定命令的處理 */final void reject(Runnable command) {handler.rejectedExecution(command, this);} }自定義 RejectedExecutionHandler 處理拒絕任務(wù)的情況 ;
實(shí)現(xiàn) rejectedExecution 方法 , 當(dāng) 線程池任務(wù)隊(duì)列飽和 , 或者 沒有空閑線程 時(shí) , 線程池被關(guān)閉 時(shí) , 導(dǎo)致線程池的任務(wù)隊(duì)列無法接受該任務(wù)時(shí) , 會(huì)調(diào)用該方法
/*** 處理添加任務(wù)失敗情況的 handler * 用戶可以自定義該接口 */ public interface RejectedExecutionHandler {/*** * 無法接受任務(wù)時(shí)執(zhí)行該方法 ;* 當(dāng)線程池任務(wù)隊(duì)列飽和 , 或者沒有空閑線程時(shí) , 線程池被關(guān)閉時(shí) , 會(huì)調(diào)用該方法** 該方法可能會(huì)觸發(fā) RejectedExecutionException 異常 , 用戶需要捕獲并處理該異常** @param r 被拒絕的任務(wù)* @param executor 嘗試執(zhí)行該任務(wù)的執(zhí)行者* @throws RejectedExecutionException 如果沒有補(bǔ)救方法, 拋出該異常*/void rejectedExecution(Runnable r, ThreadPoolExecutor executor); }
二、線程池 addWorker 添加任務(wù)
檢查一個(gè)新的工作者 ( Worker ) 是否可以被添加 , 根據(jù)當(dāng)前的 線程池狀態(tài) , 和 給定的核心線程數(shù) , 最大線程數(shù) 等判定 ;
如果可以添加 , 那么先 調(diào)整 工作者 ( Worker ) 的個(gè)數(shù) , 然后 創(chuàng)建新的 工作者 ( Worker ) , 并 將參數(shù)中的 Runnable firstTask 設(shè)置為第一個(gè)任務(wù) ;
如果線程池停止或關(guān)閉 , 返回 false ;
如果線程創(chuàng)建失敗 , 不管是線程工廠返回空 , 還是出現(xiàn) OOM , 直接退出 ;
如果當(dāng)前的 線程個(gè)數(shù)少于 核心線程數(shù) , 或者當(dāng)前的 任務(wù)數(shù)已滿 , 則必須創(chuàng)建 工作者 ( Worker ) , 并執(zhí)行第一個(gè)初始任務(wù) ,
public class ThreadPoolExecutor extends AbstractExecutorService {/*** 檢查一個(gè)新的工作者是否可以被添加 , 根據(jù)當(dāng)前的線程池狀態(tài) , 和給定的核心線程數(shù) , 最大線程數(shù)等判定 ;* 如果可以添加 , 那么先調(diào)整 工作者 ( Worker ) 的個(gè)數(shù) , 然后創(chuàng)建新的 工作者 ( Worker ) , * 并將參數(shù)中的 Runnable firstTask 設(shè)置為第一個(gè)任務(wù) ; * 如果線程池停止或關(guān)閉 , 返回 false ; * 如果線程創(chuàng)建失敗 , 不管是線程工廠返回空 , 還是出現(xiàn) OOM , 直接退出 ; ** 第一個(gè)運(yùn)行的任務(wù) ; * 如果當(dāng)前的線程個(gè)數(shù)少于 核心線程數(shù) , 或者當(dāng)前的任務(wù)數(shù)已滿 , * 必須創(chuàng)建 工作者 ( Worker ) , 并執(zhí)行第一個(gè)初始任務(wù) , ** @param core 如果設(shè)置為 true , 必須使用核心線程綁定 * @return true if successful*/private boolean addWorker(Runnable firstTask, boolean core) {retry:// 死循環(huán)for (;;) {int c = ctl.get();int rs = runStateOf(c);// 查看隊(duì)列是否為空// 查看線程池是否 SHUTDOWN if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;// 查看線程池的線程個(gè)數(shù) , 與 核心線程數(shù), 最大線程數(shù) 進(jìn)行各種對(duì)比// 獲取現(xiàn)在的線程池情況 for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;// 如果沒有達(dá)到最大線程數(shù) , 允許添加 if (compareAndIncrementWorkerCount(c)) // 該行代碼只是將計(jì)數(shù)器 +1break retry;c = ctl.get(); // Re-read ctlif (runStateOf(c) != rs)continue retry;// else CAS failed due to workerCount change; retry inner loop}}// 下面是添加一個(gè)線程的邏輯 boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {// 創(chuàng)建工作者 , 并將任務(wù)設(shè)置給該工作者 w = new Worker(firstTask);// 線程是從工作者中取出的 , 該線程是在 Worker 構(gòu)造函數(shù)中使用線程工廠創(chuàng)建的 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();// 將工作者設(shè)置給 工作者集合 workers.add(w);int s = workers.size();if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}// 如果添加成功 , 就會(huì)啟動(dòng) Worker 中的線程 if (workerAdded) {t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;} }總結(jié)
以上是生活随笔為你收集整理的【Android 异步操作】线程池 ( 线程池 reject 拒绝任务 | 线程池 addWorker 添加任务 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 异步操作】线程池 (
- 下一篇: 【Android 异步操作】线程池 (