知道執行緒池的四種拒絕策略嗎?

AnonyStar發表於2020-10-29



  • 在之前的文章中我們知道了執行緒池各個引數的含義,其中有個引數handler 我們說了是拒絕策略,具體關於執行緒池的拒絕策略我們這篇文章來分析

  • 首先我們要理解執行緒池的拒絕策略的作用,它是用來處理當執行緒池無法繼續處理更多的任務時的處理機制,那麼首先我們要知道拒絕策略的觸發時機,我麼們來看下面程式碼:

 ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(
                        1,
                        2,
                        1,
                        TimeUnit.MILLISECONDS,
                        new LinkedBlockingQueue<>(),
                        new ThreadPoolExecutor.DiscardOldestPolicy()
                );

執行緒池的拒絕時機

  • 第一種,當我們正常關閉執行緒池時也就是使用shutdown 等方法,這時候即使執行緒池中還有未完成的任務正在執行,但是由於執行緒池已經關閉,所以這時候我們再繼續向執行緒池提交任務的話就會被拒絕

  • 第二種,當執行緒池沒有能力再繼續處理提交的任務,如佇列已滿,最大執行緒數達到,這時候執行緒池就處於飽和狀態


在我們需要學習和了解的就是第二種,在實際開發中我們需要解決這種情況,關於執行緒池執行的流程可以看之前我們文章,也可關注 i-code.online 部落格。

拒絕策略

  • 首先我們知道執行緒池的拒絕策略引數的型別是 RejectedExecutionHandler 型別的,那麼我們可以先來了解一下關於這個介面的關係


  • 在上述類圖中我們可以看到 RejectedExecutionHandler 介面有四個實現類,同時都提供了無參建構函式,這四個實現類對應了不同的拒絕策略,都有各自的適用場景

  • **AbortPolicy **拒絕策略:這種策略在拒絕任務時,會直接丟擲一個型別為 RejectedExecutionExceptionRuntimeException,讓你感知到任務被拒絕了,於是你便可以根據業務邏輯選擇重試或者放棄提交等策略。

  • DiscardPolicy 拒絕策略:這種策略是當任務提交時直接將剛提交的任務丟棄,而且不會給與任何提示通知,所以這種策略使用要慎重,因為有一定的風險,對我們來說根本不知道提交的任務有沒有被丟棄

  • DiscardOldestPolicy 拒絕策略:這種策略和上面相似。不過它丟棄的是佇列中的頭節點,也就是存活時間最久的


  • CallerRunsPolicy 拒絕策略:這種策略算是最完善的相對於其他三個,當執行緒池無能力處理當前任務時,會將這個任務的執行權交予提交任務的執行緒來執行,也就是誰提交誰負責,這樣的話提交的任務就不會被丟棄而造成業務損失,同時這種誰提交誰負責的策略必須讓提交執行緒來負責執行,如果任務比較耗時,那麼這段時間內提交任務的執行緒也會處於忙碌狀態而無法繼續提交任務,這樣也就減緩了任務的提交速度,這相當於一個負反饋。也有利於執行緒池中的執行緒來消化任務


本文由AnonyStar 釋出,可轉載但需宣告原文出處。
歡迎關注微信公賬號 :雲棲簡碼 獲取更多優質文章
更多文章關注筆者部落格 :雲棲簡碼 i-code.online

相關文章