完全解析Android多線程中線程池ThreadPool的原理和使用
前言對于多線程,大家應該很熟悉。但是,大家了解線程池嗎?今天,我將帶大家全部學習關于線程池的所有知識。
目錄

1. 簡介

2. 工作原理
2.1 核心參數(shù)線程池中有6個核心參數(shù),具體如下

上述6個參數(shù)的配置 決定了 線程池的功能,具體設置時機 = 創(chuàng)建 線程池類對象時 傳入
ThreadPoolExecutor類 = 線程池的真正實現(xiàn)類
開發(fā)者可根據(jù)不同需求 配置核心參數(shù),從而實現(xiàn)自定義線程池
// 創(chuàng)建線程池對象如下
// 通過 構造方法 配置核心參數(shù)
Executor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
sPoolWorkQueue,
sThreadFactory
);
// 構造函數(shù)源碼分析
public ThreadPoolExecutor (int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable workQueue>,
ThreadFactory threadFactory )
注:Java 里已內置4種常用的線程池(即 已經配置好核心參數(shù)),下面會詳細說明
2.2 內部原理邏輯
當線程池運行時,遵循以下工作邏輯

3. 使用流程
線程池的使用流程如下
// 1. 創(chuàng)建線程池
// 創(chuàng)建時,通過配置線程池的參數(shù),從而實現(xiàn)自己所需的線程池
Executor threadPool = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
sPoolWorkQueue,
sThreadFactory
);
// 注:在Java中,已內置4種常見線程池,下面會詳細說明
// 2. 向線程池提交任務:execute()
// 說明:傳入 Runnable對象
threadPool.execute(new Runnable() {
@Override
public void run() {
... // 線程執(zhí)行任務
}
});
// 3. 關閉線程池shutdown()
threadPool.shutdown();
// 關閉線程的原理
// a. 遍歷線程池中的所有工作線程
// b. 逐個調用線程的interrupt()中斷線程(注:無法響應中斷的任務可能永遠無法終止)
// 也可調用shutdownNow()關閉線程:threadPool.shutdownNow()
// 二者區(qū)別:
// shutdown:設置 線程池的狀態(tài) 為 SHUTDOWN,然后中斷所有沒有正在執(zhí)行任務的線程
// shutdownNow:設置 線程池的狀態(tài) 為 STOP,然后嘗試停止所有的正在執(zhí)行或暫停任務的線程,并返回等待執(zhí)行任務的列表
// 使用建議:一般調用shutdown()關閉線程池;若任務不一定要執(zhí)行完,則調用shutdownNow()
4. 常見的4類功能線程池
根據(jù)參數(shù)的不同配置,Java中最常見的線程池有4類:
定長線程池(FixedThreadPool)定時線程池(ScheduledThreadPool )可緩存線程池(CachedThreadPool)單線程化線程池(SingleThreadExecutor)
即 對于上述4類線程池,Java已根據(jù) 應用場景 配置好核心參數(shù)
4.1 定長線程池(FixedThreadPool)特點:只有核心線程 & 不會被回收、線程數(shù)量固定、任務隊列無大小限制(超出的線程任務會在隊列中等待)應用場景:控制線程最大并發(fā)數(shù)具體使用:通過 Executors.newFixedThreadPool() 創(chuàng)建示例:
// 1. 創(chuàng)建定長線程池對象 & 設置線程池線程數(shù)量固定為3
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
// 2. 創(chuàng)建好Runnable類線程對象 & 需執(zhí)行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執(zhí)行任務啦");
}
};
// 3. 向線程池提交任務:execute()
fixedThreadPool.execute(task);
// 4. 關閉線程池
fixedThreadPool.shutdown();
4.2 定時線程池(ScheduledThreadPool )特點:核心線程數(shù)量固定、非核心線程數(shù)量無限制(閑置時馬上回收)應用場景:執(zhí)行定時 / 周期性 任務使用:通過Executors.newScheduledThreadPool()創(chuàng)建示例:
// 1. 創(chuàng)建 定時線程池對象 & 設置線程池線程數(shù)量固定為5
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
// 2. 創(chuàng)建好Runnable類線程對象 & 需執(zhí)行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執(zhí)行任務啦");
}
};
// 3. 向線程池提交任務:schedule()
scheduledThreadPool.schedule(task, 1, TimeUnit.SECONDS); // 延遲1s后執(zhí)行任務
scheduledThreadPool.scheduleAtFixedRate(task,10,1000,TimeUnit.MILLISECONDS);// 延遲10ms后、每隔1000ms執(zhí)行任務
// 4. 關閉線程池
scheduledThreadPool.shutdown();
4.3 可緩存線程池(CachedThreadPool)特點:只有非核心線程、線程數(shù)量不固定(可無限大)、靈活回收空閑線程(具備超時機制,全部回收時幾乎不占系統(tǒng)資源)、新建線程(無線程可用時)
任何線程任務到來都會立刻執(zhí)行,不需要等待
應用場景:執(zhí)行大量、耗時少的線程任務 使用:通過Executors.newCachedThreadPool()創(chuàng)建 示例:
// 1. 創(chuàng)建可緩存線程池對象
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 2. 創(chuàng)建好Runnable類線程對象 & 需執(zhí)行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執(zhí)行任務啦");
}
};
// 3. 向線程池提交任務:execute()
cachedThreadPool.execute(task);
// 4. 關閉線程池
cachedThreadPool.shutdown();
//當執(zhí)行第二個任務時第一個任務已經完成
//那么會復用執(zhí)行第一個任務的線程,而不用每次新建線程。
4.4 單線程化線程池(SingleThreadExecutor)
特點:只有一個核心線程(保證所有任務按照指定順序在一個線程中執(zhí)行,不需要處理線程同步的問題)
應用場景:不適合并發(fā)但可能引起IO阻塞性及影響UI線程響應的操作,如數(shù)據(jù)庫操作,文件操作等
使用:通過Executors.newSingleThreadExecutor()創(chuàng)建示例:
// 1. 創(chuàng)建單線程化線程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 2. 創(chuàng)建好Runnable類線程對象 & 需執(zhí)行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執(zhí)行任務啦");
}
};
// 3. 向線程池提交任務:execute()
singleThreadExecutor.execute(task);
// 4. 關閉線程池
singleThreadExecutor.shutdown();
4.5 常見線程池 總結 & 對比

5. 總結閱讀本文后,相信你已經非常了解線程池 & 用法接下來,我會繼續(xù)講解Android開發(fā)中關于多線程的知識,具體包括Thread類、Handler、HandlerThread等等,有興趣可以繼續(xù)關注Carson_Ho的安卓開發(fā)筆記請幫頂 / 評論點贊!因為你的鼓勵是我寫作的最大動力!
相關文章
Android邊播放邊緩存視頻框架AndroidVideoCache詳解
這篇文章主要為大家介紹了Android邊播放邊緩存視頻框架AndroidVideoCache詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Android編程實現(xiàn)webview將網頁打包成apk的方法
這篇文章主要介紹了Android編程實現(xiàn)webview將網頁打包成apk的方法,以打包HTML5為例分析了webview打包apk的相關方法、屬性與事件操作技巧,需要的朋友可以參考下2017-08-08
Android異步加載數(shù)據(jù)和圖片的保存思路詳解
這篇文章主要介紹了Android異步加載數(shù)據(jù)和圖片的保存思路詳解的相關資料,需要的朋友可以參考下2016-04-04
如何使用Flutter實現(xiàn)58同城中的加載動畫詳解
這篇文章主要給大家介紹了關于如何使用Flutter實現(xiàn)58同城中加載動畫詳?shù)南嚓P資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Flutter具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-10-10

