接文章Java8線程池——底層為LinkedBlockingQueue的ThreadPoolExecutor劲厌,文章中簡(jiǎn)單介紹了線程池保持線程旬盯,并且從阻塞隊(duì)列中獲取任務(wù)執(zhí)行的流程齐唆。本篇文章詳細(xì)介紹線程池的幾個(gè)重要的參數(shù)蘸泻,以重要參數(shù)為線索更詳細(xì)剖析線程池的實(shí)現(xiàn)細(xì)節(jié)。
參數(shù)corePoolSize——線程池的基本大小
線程池的目標(biāo)大小御滩,即在沒有任務(wù)執(zhí)行時(shí)線程池的大小眶痰,并且只有在工作隊(duì)列滿了的情況下才會(huì)創(chuàng)建超出這個(gè)數(shù)量的線程绢彤。
- 沒有任務(wù)執(zhí)行時(shí)線程池的大小,具體說是一個(gè)延時(shí)初始化颈墅,在線程池初始化的時(shí)候蜡镶,并不會(huì)同時(shí)初始化線程,只有當(dāng)任務(wù)到來時(shí)才會(huì)進(jìn)行線程的創(chuàng)建恤筛,并且線程創(chuàng)建后會(huì)把這個(gè)任務(wù)作為其第一個(gè)任務(wù)執(zhí)行官还。
- 只有在工作隊(duì)列滿了,這里的隊(duì)列就是線程池中定義的阻塞隊(duì)列毒坛,阻塞隊(duì)列可以設(shè)置大小望伦,默認(rèn)的長度是整型的最大值Integer.MAX_VALUE。
參數(shù)maximumPoolSize——線程池的最大線程數(shù)
表示可以同時(shí)活動(dòng)的線程數(shù)量的上限煎殷。如果某個(gè)線程的空閑時(shí)間超過了存活時(shí)間屯伞,那么將被標(biāo)記為可回收的,并且當(dāng)線程池的當(dāng)前大小超過了基本大小時(shí)豪直,這個(gè)線程將被終止劣摇。其實(shí)在實(shí)際之中還有一個(gè)參數(shù)的設(shè)置allowCoreThreadTimeOut,設(shè)置true弓乙,允許線程池中所有的線程超時(shí)末融,這時(shí)不再需要線程數(shù)量超過基本大小這個(gè)判斷條件。
代碼片段如下:
- 如何實(shí)現(xiàn)的超時(shí)時(shí)間判斷暇韧?利用阻塞隊(duì)列的等待超時(shí)機(jī)制實(shí)現(xiàn)勾习,如果在設(shè)定的時(shí)間內(nèi)取不到任務(wù),返回null懈玻,會(huì)把變量timedOut設(shè)置為true巧婶,表示已經(jīng)超時(shí)。
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
- 在參數(shù)allowCoreThreadTimeOut和判斷當(dāng)前線程是否超過基本大小共同影響下酪刀,設(shè)置timed參數(shù)的值粹舵。
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
- 變量timedOut和timed同時(shí)為true時(shí),根據(jù)判斷會(huì)終止線程骂倘。否則線程繼續(xù)for循環(huán)進(jìn)行自旋眼滤,等待任務(wù)的到來。
if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c)
return null;
continue;
}
getTask方法如下圖:
參數(shù)keepAliveTime——超出基本大小的線程空閑狀態(tài)的最長時(shí)間
如果變量allowCoreThreadTimeOut設(shè)置為true历涝,所有線程都會(huì)可能超時(shí)诅需,默認(rèn)為false漾唉,只有超出基本大小的線程會(huì)超時(shí)。線程空閑的時(shí)間超過keepAliveTime堰塌,并且線程數(shù)量大于基本大小赵刑,線程會(huì)被終止。具體實(shí)現(xiàn)參看上面參數(shù)maximumPoolSize中講解的代碼场刑。
RejectedExecutionHandler飽和策略
當(dāng)有界隊(duì)列被填滿后般此,飽和策略發(fā)揮作用,可以通過調(diào)用setRejectedExecutionHandler設(shè)置牵现。默認(rèn)策略是拋出未檢查的異常RejectedExecutionException铐懊,調(diào)用者可以捕獲這個(gè)異常,根據(jù)需求處理瞎疼,也可以快速定位到隊(duì)列被填滿科乎。另外,還有策略直接拋棄到來的任務(wù)贼急,或者拋棄下一個(gè)將被執(zhí)行的任務(wù)茅茂,嘗試提交新的任務(wù)。最后還可以實(shí)現(xiàn)將任務(wù)既不遺棄太抓,也不拋出異常空闲,而是把任務(wù)回退給調(diào)用者。在ThreadPoolExecutor中對(duì)應(yīng)的類分別是:AbortPolicy腻异,DiscardPolicy进副,DiscardOldestPolicy和CallerRunsPolicy。