關(guān)于線程池的連環(huán)21問
1失受、為什么會有線程池讶泰?
2、簡單手寫一個線程池拂到?
3峻厚、為什么要把任務(wù)先放在任務(wù)隊列里面,而不是把線程先拉滿到最大線程數(shù)谆焊?
4惠桃、線程池如何動態(tài)修改核心線程數(shù)和最大線程數(shù)?
5、如果你是 JDK 設(shè)計者辜王,如何設(shè)計劈狐?
6、如果要讓你設(shè)計一個線程池呐馆,你要怎么設(shè)計肥缔?
7、你是如何理解核心線程的汹来?
8续膳、你是怎么理解 KeepAliveTime 的?
9收班、那 workQueue 有什么用坟岔?
10、你是如何理解拒絕策略的摔桦?
11社付、你說你看過源碼,那你肯定知道線程池里的 ctl 是干嘛的咯邻耕?
12鸥咖、你知道線程池有幾種狀態(tài)嗎?
13兄世、你知道線程池的狀態(tài)是如何變遷的嗎啼辣?
14、如何修改原生線程池御滩,使得可以先拉滿線程數(shù)再入任務(wù)隊列排隊鸥拧?
15、Tomcat 中的定制化線程池實現(xiàn) 如果線程池中的線程在執(zhí)行任務(wù)的時候艾恼,拋異常了住涉,會怎么樣?
16钠绍、原生線程池的核心線程一定伴隨著任務(wù)慢慢創(chuàng)建的嗎舆声?
17、線程池的核心線程在空閑的時候一定不會被回收嗎柳爽?
18媳握、corePoolSize=0會怎么樣?
19磷脯、線程池創(chuàng)建之后蛾找,會立即創(chuàng)建核心線程么?
20赵誓、核心線程永遠(yuǎn)不會銷毀么打毛?
21柿赊、空閑線程過多會有什么問題?
下面將對理解線程池的原理幻枉、源碼介紹碰声,并逐步回答上述經(jīng)典問題。當(dāng)然熬甫,如果您對線程池的源碼熟記于心胰挑,則就沒看下去的必要。
2.https://mp.weixin.qq.com/s/7fluKiSaMnhfmHBNOOBjOQ
最佳實踐總結(jié)
【強制】使用ThreadPoolExecutor的構(gòu)造函數(shù)聲明線程池瞻颂,避免使用Executors類的 newFixedThreadPool和newCachedThreadPool。
【強制】 創(chuàng)建線程或線程池時請指定有意義的線程名稱郑象,方便出錯時回溯贡这。即threadFactory參數(shù)要構(gòu)造好。
【建議】建議不同類別的業(yè)務(wù)用不同的線程池扣唱。
【建議】CPU密集型任務(wù)(N+1):這種任務(wù)消耗的主要是CPU資源藕坯,可以將線程數(shù)設(shè)置為N(CPU核心數(shù))+1团南,比CPU核心數(shù)多出來的一個線程是為了防止線程偶發(fā)的缺頁中斷噪沙,或者其它原因?qū)е碌娜蝿?wù)暫停而帶來的影響。一旦任務(wù)暫停吐根,CPU就會處于空閑狀態(tài)正歼,而在這種情況下多出來的一個線程就可以充分利用CPU的空閑時間。
【建議】I/O密集型任務(wù)(2N):這種任務(wù)應(yīng)用起來拷橘,系統(tǒng)會用大部分的時間來處理I/O交互局义,而線程在處理I/O的時間段內(nèi)不會占用CPU來處理,這時就可以將CPU交出給其它線程使用冗疮。因此在I/O密集型任務(wù)的應(yīng)用中萄唇,我們可以多配置一些線程,具體的計算方法是2N术幔。
【建議】workQueue不要使用無界隊列另萤,盡量使用有界隊列。避免大量任務(wù)等待诅挑,造成OOM四敞。
【建議】如果是資源緊張的應(yīng)用,使用allowsCoreThreadTimeOut可以提高資源利用率拔妥。
【建議】雖然使用線程池有多種異常處理的方式忿危,但在任務(wù)代碼中,使用try-catch最通用没龙,也能給不同任務(wù)的異常處理做精細(xì)化铺厨。
【建議】對于資源緊張的應(yīng)用缎玫,如果擔(dān)心線程池資源使用不當(dāng),可以利用ThreadPoolExecutor的API實現(xiàn)簡單的監(jiān)控解滓,然后進(jìn)行分析和優(yōu)化碘梢。