【Android 异步操作】线程池 ( 线程池使用示例 | 自定义线程池使用流程 | 自定义任务拒绝处理策略 | 完整代码示例 )
文章目錄
- 一、自定義線程池使用流程
- 二、自定義任務(wù)拒絕處理策略
- 三、完整代碼示例
在博客 【Android 異步操作】線程池 ( 線程池簡介 | 線程池初始化方法 | 線程池種類 | AsyncTask 使用線程池示例 ) 中 , 簡單介紹了 線程池 , 以及 Java 提供的四個基本線程池 , 線程池的 基本工作機(jī)制 , 如核心線程 , 非核心線程 等 ;
在博客 【Android 異步操作】線程池 ( 線程池 execute 方法源碼解析 ) 中 , 講解 線程池 ThreadPoolExecutor 的 execute 方法時 , 有兩個重要的核心方法 ;
兩個核心的操作 :
- 添加任務(wù) : addWorker(command, true) , 第二個參數(shù)為 true 是添加核心線程任務(wù) , 第二個參數(shù)為 false 是添加非核心線程任務(wù) ;
- 拒絕任務(wù) : reject(command)
在博客 【Android 異步操作】線程池 ( 線程池 reject 拒絕任務(wù) | 線程池 addWorker 添加任務(wù) ) 介紹了 addWorker 添加任務(wù) , reject 拒絕任務(wù) 的源碼細(xì)節(jié) ;
在博客 【Android 異步操作】線程池 ( Worker 簡介 | 線程池中的工作流程 runWorker | 從線程池任務(wù)隊(duì)列中獲取任務(wù) getTask ) 中介紹了 工作者 Worker 的工作流程 ;
本博客中簡單介紹線程池的使用示例
一、自定義線程池使用流程
1 . 定義線程工廠 : 該線程工廠用于 創(chuàng)建線程池中的線程 ;
/*** 線程工廠* 用于創(chuàng)建線程*/private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);public Thread newThread(Runnable r) {return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());}};2 . 線程池任務(wù)隊(duì)列 : 指定 BlockingQueue<Runnable> 類型的線程池隊(duì)列 , 同時指定隊(duì)列大小 ;
/*** 線程池任務(wù)隊(duì)列* 最多可以容納 128 個可執(zhí)行的任務(wù)*/private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(128);3 . 初始化線程池 : 調(diào)用 ThreadPoolExecutor 的 構(gòu)造函數(shù) 初始化線程池 , 并對線程池進(jìn)行配置 , 配置內(nèi)容包括如下內(nèi)容 :
- 核心線程數(shù)
- 最大線程數(shù)
- 非核心線程最大限制時間
- 閑置時間的時間單位
- 線程池任務(wù)隊(duì)列
- 線程創(chuàng)建工廠
4 . 自定義任務(wù)拒絕處理策略 : 處理任務(wù)隊(duì)列已滿 , 拒絕任務(wù)的情況 ;
THREAD_POOL_EXECUTOR.setRejectedExecutionHandler(new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {// 自定義任務(wù)被拒絕后的處理策略System.out.println("任務(wù)被拒絕");}});5 . 執(zhí)行任務(wù) : 調(diào)用線程池的 execute 方法執(zhí)行任務(wù) ;
THREAD_POOL_EXECUTOR.execute(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1_000);} catch (InterruptedException e) {e.printStackTrace();}}});二、自定義任務(wù)拒絕處理策略
如果執(zhí)行的任務(wù)時 , 當(dāng)前的線程池任務(wù)隊(duì)列已滿 , 此時就會拒絕任務(wù) , 并拋出 RejectedExecutionException 異常 ;
報錯信息如下 :
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task kim.hsl.threadpool.ThreadPool$2@1f32e575 rejected from java.util.concurrent.ThreadPoolExecutor@279f2327[Running, pool size = 17, active threads = 17, queued tasks = 128, completed tasks = 0] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at kim.hsl.threadpool.ThreadPool.main(ThreadPool.java:90)解決方案 : 為線程池設(shè)置 RejectedExecutionHandler , 該處理器需要開發(fā)者自定義 , 實(shí)現(xiàn) RejectedExecutionHandler 接口 , 并實(shí)現(xiàn)其 rejectedExecution 方法 ;
THREAD_POOL_EXECUTOR.setRejectedExecutionHandler(new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {// 自定義任務(wù)被拒絕后的處理策略System.out.println("任務(wù)被拒絕");}});三、完整代碼示例
package kim.hsl.threadpool;import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger;public class ThreadPool {/*自定義線程池使用示例自己配置線程池的各種參數(shù)模仿 AsyncTask 使用線程池部分代碼從 AsyncTask 類中拷貝過來*//*** 獲取當(dāng)前的 CPU 核數(shù)*/private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();/*** 線程池核心線程數(shù)* 線程池中最少 2 個線程 , 最多 4 個線程 ,* 最好是選擇 CPU 核數(shù) - 1 個 , 避免后臺任務(wù)使 CPU 性能飽和*/private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));/*** 最大線程數(shù)*/private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;/*** 非核心線程最大閑置時間*/private static final int KEEP_ALIVE_SECONDS = 30;/*** 線程工廠* 用于創(chuàng)建線程*/private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);public Thread newThread(Runnable r) {return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());}};/*** 線程池任務(wù)隊(duì)列* 最多可以容納 128 個可執(zhí)行的任務(wù)*/private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(128);/*** 并行執(zhí)行任務(wù)的線程池執(zhí)行者*/public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR;static {/*在靜態(tài)代碼塊中初始化線程池在構(gòu)造函數(shù)中對線程池進(jìn)行配置 , 配置內(nèi)容包括 :核心線程數(shù)最大線程數(shù)非核心線程最大限制時間閑置時間的時間單位線程池任務(wù)隊(duì)列線程創(chuàng)建工廠*/ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,sPoolWorkQueue, sThreadFactory);threadPoolExecutor.allowCoreThreadTimeOut(true);THREAD_POOL_EXECUTOR = threadPoolExecutor;}public static void main(String[] args) {THREAD_POOL_EXECUTOR.setRejectedExecutionHandler(new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {// 自定義任務(wù)被拒絕后的處理策略System.out.println("任務(wù)被拒絕");}});/*線程池中只有 128 個任務(wù)隊(duì)列 , 一次性寫入 150 個任務(wù)隊(duì)列滿了以后, 會拒絕任務(wù)報錯信息如下 :Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task kim.hsl.threadpool.ThreadPool$2@1f32e575 rejected from java.util.concurrent.ThreadPoolExecutor@279f2327[Running, pool size = 17, active threads = 17, queued tasks = 128, completed tasks = 0]at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)at kim.hsl.threadpool.ThreadPool.main(ThreadPool.java:90)*/for(int i = 0; i < 150; i ++ ){THREAD_POOL_EXECUTOR.execute(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1_000);} catch (InterruptedException e) {e.printStackTrace();}}});}}}
運(yùn)行結(jié)果 :
---- IntelliJ IDEA coverage runner ---- sampling ... include patterns: kim\.hsl\.threadpool\..* exclude patterns: 任務(wù)被拒絕 任務(wù)被拒絕 任務(wù)被拒絕 任務(wù)被拒絕 任務(wù)被拒絕 Class transformation time: 0.018846207s for 141 classes or 1.336610425531915E-4s per class總結(jié)
以上是生活随笔為你收集整理的【Android 异步操作】线程池 ( 线程池使用示例 | 自定义线程池使用流程 | 自定义任务拒绝处理策略 | 完整代码示例 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 异步操作】线程池 (
- 下一篇: 【词汇】ab-前缀、al-后缀、norm