Java開發之Java線程池原理分析學習

使用線程池的好處

1、降低資源消耗

可以重複利用已創建的線程降低線程創建和銷燬造成的消耗。

2、提高響應速度

當任務到達時,任務可以不需要等到線程創建就能立即執行。

3、提高線程的可管理性

線程是稀缺資源,如果無限制地創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控

線程池的工作原理

首先我們看下當一個新的任務提交到線程池之後,線程池是如何處理的

1、線程池判斷核心線程池裏的線程是否都在執行任務。如果不是,則創建一個新的工作線程來執行任務。如果核心線程池裏的線程都在執行任務,則執行第二步。

2、線程池判斷工作隊列是否已經滿。如果工作隊列沒有滿,則將新提交的任務存儲在這個工作隊列裏進行等待。如果工作隊列滿了,則執行第三步

3、線程池判斷線程池的線程是否都處於工作狀態。如果沒有,則創建一個新的工作線程來執行任務。如果已經滿了,則交給飽和策略來處理這個任務

線程池飽和策略

這裏提到了線程池的飽和策略,那我們就簡單介紹下有哪些飽和策略:

AbortPolicy

爲Java線程池默認的阻塞策略,不執行此任務,而且直接拋出一個運行時異常,切記ThreadPoolExecutor.execute需要try catch,否則程序會直接退出。

DiscardPolicy

直接拋棄,任務不執行,空方法

DiscardOldestPolicy

從隊列裏面拋棄head的一個任務,並再次execute 此task。

CallerRunsPolicy

在調用execute的線程裏面執行此command,會阻塞入口

用戶自定義拒絕策略(最常用)

實現RejectedExecutionHandler,並自己定義策略模式

下我們以ThreadPoolExecutor爲例展示下線程池的工作流程圖

1、如果當前運行的線程少於corePoolSize,則創建新線程來執行任務(注意,執行這一步驟需要獲取全局鎖)。

2、如果運行的線程等於或多於corePoolSize,則將任務加入BlockingQueue。

3、如果無法將任務加入BlockingQueue(隊列已滿),則在非corePool中創建新的線程來處理任務(注意,執行這一步驟需要獲取全局鎖)。

4、如果創建新線程將使當前運行的線程超出maximumPoolSize,任務將被拒絕,並調用RejectedExecutionHandler.rejectedExecution()方法。

ThreadPoolExecutor採取上述步驟的總體設計思路,是爲了在執行execute()方法時,儘可能地避免獲取全局鎖(那將會是一個嚴重的可伸縮瓶頸)。在ThreadPoolExecutor完成預熱之後(當前運行的線程數大於等於corePoolSize),幾乎所有的execute()方法調用都是執行步驟2,而步驟2不需要獲取全局鎖。

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