Android 中的線程池就是 java 中的線程池,即 ThreadPoolExecutor 類搀绣。
Java 通過(guò) Executors 提供四種線程池:
- newCachedThreadPool
創(chuàng)建一個(gè)可緩存的線程池
- newFixedThreadPool
創(chuàng)建一個(gè)定長(zhǎng)線程池栋艳,可控制線程最大并發(fā)數(shù)恰聘,超出的線程會(huì)在隊(duì)列中等待。
- newScheduledThreadPool
創(chuàng)建一個(gè)定長(zhǎng)線程池吸占,支持定時(shí)及周期性任務(wù)執(zhí)行晴叨。
- newSingleThreadExecutor
創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù)矾屯,保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行兼蕊。
Executors 是一個(gè)線程池的工具類,上面四個(gè)方法最終都是調(diào)用的 ThreadPoolExecutor
件蚕。理解 ThreadPoolExecutor 就可以完全理解線程池孙技。
線程池解決了 2 個(gè)問(wèn)題:
- 當(dāng)執(zhí)行大量異步任務(wù)時(shí),通過(guò)減少每個(gè)任務(wù)的調(diào)用開(kāi)銷來(lái)提高性能排作。
- 提供了限制管理線程資源的方法牵啦。
ThreadPoolExecutor
public class ThreadPoolExecutor extends AbstractExecutorService
構(gòu)造
/**
*
* @param corePoolSize 保持在線程池中的線程數(shù),即使線程處于空閑狀態(tài)妄痪,除非設(shè)置了 allowCoreThreadTimeOut
* @param maximumPoolSize 線程最大數(shù)量
* @param keepAliveTime 線程數(shù)大于 corePoolSize 時(shí)哈雏,線程池中的空閑線程等待新任務(wù)執(zhí)行的最大時(shí)間,超過(guò)這個(gè)時(shí)間衫生,空閑線程就會(huì)被終止僧著。
* @param unit keepAliveTime 的時(shí)間單位
* @param workQueue 任務(wù)隊(duì)列
* @param threadFactory 線程工廠
* @param handler 線程被阻塞時(shí)的處理者,因?yàn)榈竭_(dá)了線程的最大數(shù)量或者任務(wù)隊(duì)列滿了障簿。
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// 檢查參數(shù)
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í)行流程
執(zhí)行流程可以用這張圖來(lái)概括:
通過(guò) execute()
方法執(zhí)行線程池,內(nèi)部會(huì)自動(dòng)根據(jù)我們構(gòu)造參數(shù)的信息分配處理 Runnable栅迄。
public void execute(Runnable command) {
// Runnable 不可以為空
if (command == null)
throw new NullPointerException();
// ctl 是一個(gè) AtomicInteger站故,用來(lái)記錄正在運(yùn)行的線程數(shù)量
int c = ctl.get();
// 當(dāng)前核心的線程數(shù)量<corePoolSize,就新開(kāi)一個(gè)線程將任務(wù)放進(jìn)去
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 核心線程正在運(yùn)行,且任務(wù)隊(duì)列沒(méi)滿
if (isRunning(c) && workQueue.offer(command)) {
// 重新檢查核心線程
int recheck = ctl.get();
// 核心線程沒(méi)有運(yùn)行就移除任務(wù)西篓,實(shí)施拒絕策略
if (! isRunning(recheck) && remove(command))
reject(command);
// 核心線程數(shù)量為0愈腾,開(kāi)一個(gè)線程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 任務(wù)隊(duì)列
else if (!addWorker(command, false))
reject(command);
}