keepAliveTime含義
看了很多文章覺得都不能把keepAliveTime的意思說的很明白,希望通過自己的理解把keepAliveTime說的明確一些
先引用一句我覺得相對說的比較明白的含義:當線程空閑時間達到keepAliveTime,該線程會退出,有兩個疑問:1、線程為什么會空閑 2、線程為什么要退出
如果我們不能把線程池各個參數的來龍去脈都梳理清楚其實是很難明白keepAliveTime的含義的
我們來舉例說明:
核心線程數10,最大線程數30,keepAliveTime是3秒
隨着任務數量不斷上升,線程池會不斷的創建線程,直到到達核心線程數10,就不創建線程了,
這時多余的任務通過加入阻塞隊列來運行,
當超出阻塞隊列長度+核心線程數時,
這時不得不擴大線程個數來滿足當前任務的運行,這時就需要創建新的線程了(最大線程數起作用),上限是最大線程數30
那么超出核心線程數10並小於最大線程數30的可能新創建的這20個線程相當於是“借”的,如果這20個線程空閑時間超過keepAliveTime,就會被退出
我們來看開頭提到的兩個問題:
1、線程為什么會空閑
2、線程為什么要退出
答:
1、沒有任務時線程就會空閑下來,在線程池中任務是任務(Runnale)線程是線程(Worker)
2、通常超出核心線程的線程是“借”的,也就是說超出核心線程的情況算是一種能夠預見的異常情況,並且這種情況並不常常發生(如果常常發生,那我想你應該調整你的核心線程數了),所以這種不經常發生而創建的線程為了避免資源浪費就應該要退出
我們需要看一下java.util.concurrent.ThreadPoolExecutor#getTask源碼來驗證上面一段話的含義:
int wc = workerCountOf(c); // Are workers subject to culling? 是否屠宰workers //當allowCoreThreadTimeOut為true或者當前任務數超過核心線程數時,timed為true boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; …… try { Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) ://如果timed為true說明worker有可能要被關閉,這里調用的代碼含義:如果超過keepAliveTime納秒還沒取到任務,就返回null,后面會調用processWorkerExit把worker關閉 workQueue.take();//否則任務隊列為空就阻塞在這里,直到任務隊列再有任務 if (r != null) return r;
10個核心線程會不會退出,由下面的參數決定:
allowCoreThreadTimeout:是否允許核心線程空閑退出,默認值為false
當keepAliveTime設置為0時到底是空閑線程直接退出還是不退出
通過實驗證明和上文代碼workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)證明,是直接不等待退出,而不是永遠不退出
這樣我們就需要注意了,這個值設置為0 並不是個很好的做法(除非場景中任務數量極少能超出核心線程數),如果任務數頻繁超出核心線程數,這個值需要評估設定為合理值盡量避免線程開啟關閉的動作
(上圖,如果永遠不退出,那么workers就不是10 而是45)