線程池:第三章:線程池的手寫改造和拒絕策略以及線程池配置合理線程數

根據阿里巴巴開發手冊:

我們線程池使用ThreadPoolExecutor的方式進行創建,下面看底層源碼:

 

有七個參數:

現在創建它:核心線程數2,同時執行的最大線程數5,多餘線程存活時間1L,單位秒,阻塞隊列3,默認線程工廠,拒絕策略

創建線程池:

第一種拒絕策略:AbortPolicy:超出最大線程數,直接拋出RejectedExecutionException異常阻止系統正常運行。 

運行五個線程:

 運行八個線程:

運行9個線程:

由此可以看出最大線程數爲:同時執行的最大線程數+任務隊列(阻塞隊列)數,超過了最大線程數直接運行拒絕策略。

 

第二種拒絕策略:

“調用者運行”一種調節機制,該策略既不會拋棄任務,也不會拋出異常,而是將某些任務回退到調用者,從而降低新任務的流量。(誰調用了你,到達最大線程數時,你回去找調用你的人,然後聽從調用你的人安排)(超出的我們能辦的給你辦,不能辦的給你回退 )

 

第三拒絕策略:DiscardOldestPolicy:拋棄隊列中等待最久的任務,然後把當前任務加入隊列中嘗試再次提交當前任務

 

第四種拒絕策略:DiscardPolicy:直接丟棄任務,不予任何處理也不拋異常,如果允許任務丟失這是最好的一種方案。

線程池配置合理線程數

查看機器的核心數

 

 
------------------------

CPU密集型:cpu的核數+1,這樣可以儘量減少切換

IO密集型:cpu的核數*10(一般阻塞系統是0.9)

業務場景:

1:高併發、任務執行時間短的業務,線程池線程數可以設置爲CPU核數+1,減少線程上下文的切換

2:併發不高、任務執行時間長的業務這就需要區分開看了:

a)假如是業務時間長集中在IO操作上,也就是IO密集型的任務,因爲IO操作並不佔用CPU,所以不要讓所有的CPU閒下來,可以適當加大線程池中的線程數目,讓CPU處理更多的業務

b)假如是業務時間長集中在計算操作上,也就是計算密集型任務,這個就沒辦法了,和(1)一樣吧,線程池中的線程數設置得少一些,減少線程上下文的切換

(其實從一二可以看出無論併發高不高,對於業務中是否是cpu密集還是I/O密集的判斷都是需要的當前前提是你需要優化性能的前提下)

3:併發高、業務執行時間長,解決這種類型任務的關鍵不在於線程池而在於整體架構的設計,看看這些業務裏面某些數據是否能做緩存是第一步,我們的項目使用的時redis作爲緩存(這類非關係型數據庫還是挺好的)。增加服務器是第二步(一般政府項目的首先,因爲不用對項目技術做大改動,求一個穩,但前提是資金充足),至於線程池的設置,設置參考 2 。最後,業務執行時間長的問題,也可能需要分析一下,看看能不能使用中間件(任務時間過長的可以考慮拆分邏輯放入隊列等操作)對任務進行拆分和解耦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章