【線程池】線程池的4種拒絕策略


線程被拒絕的場景

image.png

結合上面的圖,我們思考一個問題,當我們創建一個線程池的時候,他會有最大的線程數,和線程任務緩存數。如果系統的線程任務突然暴增,這個時候,線程池的線程達到最大值,線程隊列中的緩存數也達到了最大值,這個時候,沒有擠進線程池的該怎么辦。

在使用線程池的時候,可能會遇到兩種情況,導致線程會需要被拒絕。

  • 調用 shutdown 等方法關閉線程池后,即便此時可能線程池內部依然有沒執行完的任務正在執行,但是由於線程池已經關閉,此時如果再向線程池內提交任務,就會遭到拒絕。
  • 線程池沒有能力繼續處理新提交的任務,也就是工作已經非常飽和的時候。

線程池的拒絕Handler

其實在這里,我們其實可以想到線程池的初始配置中有一個配置handler,這個其實就是為了解決這種問題而出現的,在線程池中,除了我們自己可以定義一個拒絕Handler策略,線程池其實也內置了四種不同的拒絕策略供我們使用。

線程策略

AbortPolicy(異常策略)

在遇到拒絕任務時,會直接拋出一個類型為 RejectedExecutionException 的 RuntimeException,所以我會叫他為異常策略,因為他會拋出異常。這個異常你可以捕獲起來,然后做你想做的事。

DiscardPolicy(丟棄策略)

這個策略就比較悲傷了,當線程滿了之后,后面想進來的線程會被直接丟棄掉,丟棄掉的線程后面不會再執行,也不會有通知,更不會有記錄,所以這個策略比較危險,他會讓線程人間蒸發。這樣大家都不知道他有沒有發生過。如果發生在業務上,可能會造成業務數據的丟失。

DiscardOldestPolicy (犧牲策略)

這個就比較殘忍,雖然不會丟棄掉想要擠進來的線程,但是他會把線程隊列中存活時間久的線程給丟棄掉,讓想擠進來的線程去替代他。有點像渣男。可以把它叫為渣男策略

CallerRunsPolicy(執行策略)

這個策略就比較負責了,當線程池滿了之后,想要進來的線程不會被丟棄,他會直接讓提交線程的線程去執行這個線程任務,也是不進入到線程池,你直接就地解決吧。更簡單的理解為,當遇到了這個策略,相當於這個線程池新增了一個線程資源。
這樣的方式有兩點好處

  • 新提交的任務不會被丟棄,也就不會造成業務上的損失。
  • 新提交的任務會讓提交者的線程去執行,這個時候提交者的線程就會被阻塞一段時間,這段時間其實會給線程池減少一定程度的壓力,減緩了提交者的去提交線程的速度。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM