java.uitl.concurrent包研究
ThreadPoolExecutor幾點使用建議
先看一副圖,描述了ThreadPoolExecutor的工作機制:
整個ThreadPoolExecutor的任務處理有4步操作:
- 第一步,初始的poolSize < corePoolSize,提交的runnable任務,會直接做為new一個Thread的引數,立馬執行
-
第二步,當提交的任務數超過了corePoolSize,就進入了第二步操作。會將當前的runable提交到一個block queue中
- 第三步,如果block queue是個有界佇列,當佇列滿了之後就進入了第三步。如果poolSize < maximumPoolsize時,會嘗試new 一個Thread的進行救急處理,立馬執行對應的runnable任務
- 第四步,如果第三步救急方案也無法處理了,就會走到第四步執行reject操作。
幾點說明:(相信這些網上一搜一大把,我這裡簡單介紹下,為後面做一下鋪墊)
-
block queue有以下幾種實現:
1. ArrayBlockingQueue : 有界的陣列佇列
2. LinkedBlockingQueue : 可支援有界/無界的佇列,使用連結串列實現
3. PriorityBlockingQueue : 優先佇列,可以針對任務排序
4. SynchronousQueue : 佇列長度為1的佇列,和Array有點區別就是:client thread提交到block queue會是一個阻塞過程,直到有一個worker thread連線上來poll task。 -
RejectExecutionHandler是針對任務無法處理時的一些自保護處理:
1. Reject 直接丟擲Reject exception
2. Discard 直接忽略該runnable,不可取
3. DiscardOldest 丟棄最早入佇列的的任務
4. CallsRun 直接讓原先的client thread做為worker執行緒,進行執行
容易被人忽略的點:
1. pool threads啟動後,以後的任務獲取都會通過block queue中,獲取堆積的runnable task.
所以建議: block size >= corePoolSize ,不然執行緒池就沒任何意義
2. corePoolSize 和 maximumPoolSize的區別, 和大家正常理解的資料庫連線池不太一樣。
* 據dbcp pool為例,會有minIdle , maxActive配置。minIdle代表是常駐記憶體中的threads數量,maxActive代表是工作的最大執行緒數。
* 這裡的corePoolSize就是連線池的maxActive的概念,它沒有minIdle的概念(每個執行緒可以設定keepAliveTime,超過多少時間多有任務後銷燬執行緒,預設只會針對maximumPoolSize引數的執行緒生效,可以設定allowCoreThreadTimeOut=true,就可以對corePoolSize進行idle回收)。
* 這裡的maximumPoolSize,是一種救急措施的第一層。當threadPoolExecutor的工作threads存在滿負荷,並且block queue佇列也滿了,這時代表接近崩潰邊緣。這時允許臨時起一批threads,用來處理runnable,處理完後通過keepAliveTime進行排程回收。
所以建議: maximumPoolSize >= corePoolSize
=期望的最大執行緒數。 (我曾經配置了corePoolSize=1, maximumPoolSize=20, blockqueue為無界佇列,最後就成了單執行緒工作的pool。典型的配置錯誤)
3. 善用blockqueue和reject組合. 這裡要重點推薦下CallsRun的Rejected Handler,從字面意思就是讓呼叫者自己來執行。
我們經常會線上上使用一些執行緒池做非同步處理,比如我前面做的(業務層)非同步並行載入技術分析和設計, 將原本序列的請求都變為了並行操作,但過多的並行會增加系統的負載(比如軟中斷,上下文切換)。所以肯定需要對執行緒池做一個size限制。但是為了引入非同步操作後,避免因在block
queue的等待時間過長,所以需要在佇列滿的時,執行一個callsRun的策略,並行的操作又轉為一個序列處理,這樣就可以保證儘量少的延遲影響。
所以建議: RejectExecutionHandler = CallsRun
, blockqueue size = 2 * poolSize (為啥是2倍poolSize,主要一個考慮就是瞬間高峰處理,允許一個thread等待一個runnable任務)
相關文章
- 鏈塔智庫:2019數字錢包研究報告
- 轉爐鍊鋼防翻包安全技術研究WBI
- Python中使用語句匯入模組或包的機制研究Python
- (fanqiang) app 要如何使用 fiddle 抓包呢,有大佬有相關研究麼APP
- 中國資訊通訊研究院聯合騰訊釋出《軟體開發包(SDK)安全研究報告(2021)》
- 美國公共利益研究組織:2021年數字錢包投訴報告
- 小葫蘆資料研究院:2020遊戲直播行業資料包告遊戲行業
- 研究顯示撿到的錢包錢越多 人們越可能拾金不昧
- TCP 粘包拆包TCP
- 中國旅遊研究院:2019上半年全國文化消費資料包告
- Mob研究院:2019大學生實習市場大資料包告(附下載)大資料
- 美團研究院:2020年清明節旅遊消費復甦大資料包告大資料
- 中國信通院:2021年軟體開發包(SDK)安全研究報告(附下載)
- 中國旅遊研究院:2022年春節假日旅遊市場資料包告
- MGH:研究發現減少包裝食品中的糖分可以預防百萬起心臟病
- 中國旅遊研究院:2021年春節長假旅遊大資料包告大資料
- 01揹包、完全揹包、多重揹包詳解
- 揹包問題(01揹包與完全揹包)
- Netty - 粘包與拆包Netty
- 揹包DP——完全揹包
- 揹包DP——混合揹包
- 中國旅遊研究院&攜程:2018上半年出境旅遊大資料包告大資料
- 利用GRC進行安全研究和審計 – 將無線電訊號轉換為資料包
- 中能傳媒研究院:2022年中國能源大資料包告(附下載)大資料
- 包
- TCP粘包拆包問題TCP
- 【模板】01揹包、完全揹包
- 分組揹包、完全揹包
- Go標準包-http包serverGoHTTPServer
- tshark 抓包 mysql 協議包MySql協議
- jar包、war包和ear包的介紹與區別JAR
- 抓包概念大比較:資料包、資料包、分組
- Netty 中的粘包和拆包Netty
- 包、元包和框架(.NET Core 指南)框架
- TCP的粘包拆包技術TCP
- 粘包拆包及解決方案
- 包頭開票-包頭開票
- 中國旅遊研究院&華遠國旅:2018年中歐旅遊大資料包告大資料
- CCFA&NCBD:品牌餐飲企業預包裝食品零售狀況研究報告(附下載)