Java線程池ThreadPoolExecutor的實(shí)現(xiàn)和參數(shù)

接文章Java8線程池——底層為LinkedBlockingQueue的ThreadPoolExecutor,文章中簡單介紹了線程池保持線程,并且從阻塞隊(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ù)量的線程。

  1. 沒有任務(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í)行。
  2. 只有在工作隊(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è)判斷條件。
代碼片段如下:

  1. 如何實(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();
  1. 在參數(shù)allowCoreThreadTimeOut和判斷當(dāng)前線程是否超過基本大小共同影響下,設(shè)置timed參數(shù)的值。
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
  1. 變量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。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容