AsyncTask的內(nèi)部使用線程池處理并發(fā),要了解它是怎樣使用線程池的,那要先了解線程池的基本設(shè)置
線程池的基本參數(shù)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// ......
}
- corePoolSize: 核心線程數(shù)目,即使線程池沒(méi)有任務(wù),核心線程也不會(huì)終止(除非設(shè)置了allowCoreThreadTimeOut參數(shù)),可以理解為“常駐線程”
- maximumPoolSize: 線程池中允許的最大線程數(shù)目;一般來(lái)說(shuō),線程越多,線程調(diào)度開銷越大;因此一般都有這個(gè)限制
- keepAliveTime: 當(dāng)線程池中的線程數(shù)目比核心線程多的時(shí)候,如果超過(guò)這個(gè)keepAliveTime的時(shí)間,多余的線程會(huì)被回收;這些與核心線程相對(duì)的線程通常被稱為緩存線程
- unit: keepAliveTime的時(shí)間單位
- workQueue: 任務(wù)執(zhí)行前保存任務(wù)的隊(duì)列;這個(gè)隊(duì)列僅保存由execute提交的Runnable任務(wù)
- threadFactory: 用來(lái)構(gòu)造線程池的工廠;一般都是使用默認(rèn)的
- handler: 當(dāng)線程池由于線程數(shù)目和隊(duì)列限制而導(dǎo)致后續(xù)任務(wù)阻塞的時(shí)候,線程池的處理方式。
線程池如何調(diào)度線程
當(dāng)一個(gè)新的任務(wù)來(lái)時(shí),線程池是如何調(diào)度線程的?
- 如果線程池中線程的數(shù)目少于corePoolSize,就算線程池中有其他的沒(méi)事做的核心線程,線程池還是會(huì)重新創(chuàng)建一個(gè)核心線程;直到核心線程數(shù)目到達(dá)corePoolSize(常駐線程就位)
- 如果線程池中線程的數(shù)目大于或者等于corePoolSize,但是工作隊(duì)列workQueue沒(méi)有滿,那么新的任務(wù)會(huì)放在隊(duì)列workQueue中,按照FIFO的原則依次等待執(zhí)行;(當(dāng)有核心線程處理完任務(wù)空閑出來(lái)后,會(huì)檢查這個(gè)工作隊(duì)列然后取出任務(wù)去執(zhí)行)
- 如果線程池中線程數(shù)目大于等于corePoolSize,并且工作隊(duì)列workQueue滿了,但是總線程數(shù)目小于maximumPoolSize,那么直接創(chuàng)建一個(gè)線程處理被添加的任務(wù)。
- 如果工作隊(duì)列滿了,并且線程池中線程的數(shù)目到達(dá)了最大數(shù)目maximumPoolSize,那么就會(huì)用最后一個(gè)構(gòu)造參數(shù)
handler
處理;默認(rèn)的處理方式是直接拒絕任務(wù),然后拋出一個(gè)異常。
總結(jié)起來(lái)說(shuō),當(dāng)有新的任務(wù)要處理時(shí),先看線程池中的線程數(shù)量是否大于 corePoolSize,再看緩沖隊(duì)列 workQueue 是否滿,最后看線程池中的線程數(shù)量是否大于 maximumPoolSize。另外,當(dāng)線程池中的線程數(shù)量大于 corePoolSize 時(shí),如果里面有線程的空閑時(shí)間超過(guò)了 keepAliveTime,就將其移除線程池,這樣,可以動(dòng)態(tài)地調(diào)整線程池中線程的數(shù)量。