前言
在使用Java的任務管理框架執行任務的程序中,飽和策略在任務等待佇列已滿并且提交新任務時起作用, ThreadPollExecutor提供了四種飽和策略:

我們在上一節中介紹了它們的源代碼,本節將看到它們之間的區別,
測驗類準備
首先定義MyCommand任務并接收字串訊息:

創建一個集成測驗類,執行緒池的初始化大小為2、等待佇列大小為2、如果提交的任務大于4、則由于不同的飽和度策略,第五個任務將獲得不同的執行結果,在下一篇文章中,我們將設定不同的飽和度策略并測驗行為上的差異,

策略1:放棄通知模式
AbortPolicy是默認的飽和策略,該策略引發未經檢查的例外RejectedExecutionException,呼叫者可以捕獲此例外并根據需要撰寫代碼,例如,嘗試捕獲例外并重新發送任務,該策略仍然很友好,并且至少在銷毀任務之前會通知任務發送者,這是默認策略,因此,如果直接運行測驗準備類的第一部分,結果將是:

測驗結果:主執行緒發送4個任務后,佇列已滿,此時,提交第五項任務時,執行緒池引發了RejectedExecutionException,并且主執行緒能夠捕獲并處理該例外,
策略2:以靜默方式丟棄
DiscardPolicy,并以靜默方式接受任務,但是在例外情況下不執行任何操作,并且呼叫方不知道任務的狀態,
顯然,這對任務控制沒有幫助,因此我不推薦這種策略,
測驗結果:發送了5個執行緒,僅執行了4個任務,最后提交的任務在呼叫者不知情的情況下被無情地拋棄了,

策略3:銷毀等待時間最長的任務
DiscardOldestPolicy丟棄等待佇列中等待時間最長的任務,將其從佇列中洗掉,然后運行當前任務,這不適合等待時間最長的任務,
更改測驗策略:
exec.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
測驗結果:發送了5個執行緒,但是僅執行了4個任務,最長的等待任務c3被銷毀,呼叫者無法得知,

策略4:呼叫者執行
CallerRunsPolicy策略以提供協調機制,它不會放棄任務或引發例外,但會將任務的運行請求回傳給任務的呼叫者,并且發送任務的執行緒會自行執行,任務已發送,
測驗結果:發送了五個執行緒,但輔助執行緒僅執行了四個,而第五個任務由呼叫者執行,

結論:呼叫者執行的飽和策略實作了彈性調整機制,當作業佇列已滿時,下一個要執行的任務將在發送任務的主執行緒中執行,
當主執行緒執行任務時,執行緒資源被占用,無法發送其他任務,因此,任務提交率降低,執行緒池花費更多時間來完成排隊的任務,
策略5:呼叫方限制
前四個傳輸,這是執行緒池飽和策略,另外,任務發送者可以控制任務的發送速率,即,限制任務的發送以避免任務飽和,例如,通過使用信號量來限制任務的到達速度,此同步工具類可以控制同時訪問特定資源的運算元,您可以使用“獲取信號量”來獲取虛擬許可證,如果沒有可用的許可證,則方法呼叫執行緒將被阻塞,直到可用的許可證為止,如果執行緒池使用無限佇列來緩沖任務并且不控制任務數量,則很可能導致記憶體耗盡,然后,您可以在信號量中使用它來設定信號量上限并控制任務提交速度,將上一章中的MyCommand任務與Semaphore結合使用,以實作呼叫方控制任務發送的示例,
任務執行結果:

分析執行結果:使用semaphos將一次可以發送的任務數限制為只有兩個,任務完成后,將釋放信號燈權限,您可以有效地控制任務的提交速度,
總結
Apocalypse的受限執行緒池的四種飽和策略中,只有AbortPolicy和CallerRunPolicy對任務發送者很友好,而其他的則錯過了任務,這對于任務發送者是不利的,折衷方案是呼叫方控制任務的發送速度,并使用semaphoe根據執行緒池的配置大小來控制任務的發送,這將防止過多的任務提交,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/204499.html
標籤:Java
