線程池的幾種拒絕策略


一、簡介

  jdk1.5 版本新增了JUC並發編程包,極大的簡化了傳統的多線程開發。前面文章中介紹了線程池的使用,鏈接地址:https://www.cnblogs.com/eric-fang/p/9004020.html

  Java線程池,是典型的池化思想的產物,類似的還有數據庫的連接池、redis的連接池等。池化思想,就是在初始的時候去申請資源,創建一批可使用的連接,這樣在使用的時候,就不必再進行創建連接信息的開銷了。舉個生活中鮮明的例子,在去著名洋快餐某基或者某勞的時候,配餐人員是從一個中間的保溫箱中直接取食材,然后打包就好了。不用再臨時的來了一個單子,又要去拿原材料,又要去進行加工。效率明顯的就是提高了很多。

  俗話說 滿而不損則溢,盈而不持則傾。線程池既然是容器,那么必然的會有存滿的情況。在達到某些特定條件的時候,再來請求的話,池子是如何進行請求處理的呢?這里就引出了池的拒絕策略。一般的數據庫連接池在達到最大連接數的時候會默認的等待特定的設置的時間或者直接就拋出異常。而本文中要闡述的線程池卻並非如此的策略,下面開始展開講解下。

二、線程池的拒絕策略

  線程池中,有三個重要的參數,決定影響了拒絕策略:corePoolSize - 核心線程數,也即最小的線程數。workQueue - 阻塞隊列 。 maximumPoolSize - 最大線程數

  當提交任務數大於 corePoolSize 的時候,會優先將任務放到 workQueue 阻塞隊列中。當阻塞隊列飽和后,會擴充線程池中線程數,直到達到 maximumPoolSize 最大線程數配置。此時,再多余的任務,則會觸發線程池的拒絕策略了。

  總結起來,也就是一句話,當提交的任務數大於(workQueue.size() + maximumPoolSize ),就會觸發線程池的拒絕策略

三、拒絕策略定義

  拒絕策略提供頂級接口 RejectedExecutionHandler ,其中方法 rejectedExecution 即定制具體的拒絕策略的執行邏輯。

  jdk默認提供了四種拒絕策略:

                CallerRunsPolicy - 當觸發拒絕策略,只要線程池沒有關閉的話,則使用調用線程直接運行任務。一般並發比較小,性能要求不高,不允許失敗。但是,由於調用者自己運行任務,如果任務提交速度過快,可能導致程序阻塞,性能效率上必然的損失較大

                AbortPolicy - 丟棄任務,並拋出拒絕執行 RejectedExecutionException 異常信息。線程池默認的拒絕策略。必須處理好拋出的異常,否則會打斷當前的執行流程,影響后續的任務執行。

                DiscardPolicy - 直接丟棄,其他啥都沒有

                DiscardOldestPolicy -  當觸發拒絕策略,只要線程池沒有關閉的話,丟棄阻塞隊列 workQueue 中最老的一個任務,並將新任務加入

 

阻塞隊列說明
首先,線程池是啥,有啥好處這里就不提了.google一下馬上知道. 嘻嘻嘻

首先第一步!我們先來認識下 在 java.util.concurrent 包中,提供了 ThreadPoolExecutor 的實現。
該類是核心,參數以及含義要多多理解並記下. 源代碼如下:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

參數說明:

corePoolSize: 核心線程數,表示當前線程池主要工作的線程池數. 需要注意的是默認的初始線程數為0,當任務進來的時候才會慢慢的創建線程執行相應的任務,如果想一開始就創建所有的線程要調用prestartAllCoreThreads 方法
maximumPoolSize: 允許存在的最大線程數量,需要注意的是當核心線程數滿了,並且阻塞隊列也滿了的情況下,才回去判斷是否沒有達到最大線程數然后決定是否去創建新的線程
keepAliveTime: 當線程數量多於核心線程數的時候,空閑的線程最多存活的時間
unit: keepAliveTime的時間單位
workQueue: 當線程數目超過核心線程數時用於保存任務的隊列。主要有3種類型的BlockingQueue可供選擇:無界隊列,有界隊列和同步移交。
threadFactory: 線程工廠
handler: 阻塞隊列滿並且線程數量已達到最大值,這時候要執行的策略:一般來講有 終止,拋棄,拋棄最舊的,調用者運行


免責聲明!

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



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