日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

线程池的 RejectedExecutionHandler(拒绝策略)

發(fā)布時間:2024/2/28 64 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程池的 RejectedExecutionHandler(拒绝策略) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載自??https://blog.csdn.net/jgteng/article/details/54411423

https://blog.csdn.net/luofenghan/article/details/78596950

JAVA為多線程場景提供了線程池,下面是一個線程池的構(gòu)造方法:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), handler);}

其中這些參數(shù)的使用和說明在我的一篇文章中已經(jīng)有了介紹,如果不太清楚的可以參考這篇文章:http://blog.csdn.net/jgteng/article/details/54409887
這里想對拒絕策略RejectedExecutionHandler做一下詳細(xì)的介紹。

在使用線程池并且使用有界隊(duì)列的時候,如果隊(duì)列滿了,任務(wù)添加到線程池的時候就會有問題,針對這些問題java線程池提供了以下幾種策略:

  • AbortPolicy?(中止)?
  • DiscardPolicy?(拋棄)?
  • DiscardOldestPolicy? (拋棄最舊)?
  • CallerRunsPolicy?(調(diào)用者運(yùn)行)

自定義

AbortPolicy
該策略是線程池的默認(rèn)策略。使用該策略時,如果線程池隊(duì)列滿了丟掉這個任務(wù)并且拋出RejectedExecutionException異常。

  • 該策略是默認(rèn)的飽和策略;
  • 會拋出未檢查的RejectedExecutionException,調(diào)用者可以捕獲這個異常,然后根據(jù)需求編寫自己的處理代碼;

源碼如下:

?public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {//不做任何處理,直接拋出異常throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +e.toString());}

DiscardPolicy
這個策略和AbortPolicy的slient版本,如果線程池隊(duì)列滿了,會直接丟掉這個任務(wù)并且不會有任何異常。

  • 當(dāng)提交的任務(wù)無法保存到隊(duì)列中等待執(zhí)行時,Discard策略會悄悄拋棄該任務(wù)。

源碼如下:

? ?public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {//就是一個空的方法}

DiscardOldestPolicy

  • 會拋棄下一個將被執(zhí)行的任務(wù),然后嘗試重新提交的新任務(wù)。
  • 如果工作隊(duì)列是一個優(yōu)先隊(duì)列,那么拋棄最舊的策略,會拋棄優(yōu)先級最高的任務(wù),因此最好不要將拋棄最舊的飽和策略和優(yōu)先級隊(duì)列放在一起使用。


源碼如下:

? ? ? ? public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {//移除隊(duì)頭元素e.getQueue().poll();//再嘗試入隊(duì)e.execute(r);}}

CallerRunsPolicy

  • 該策略既不會拋棄任務(wù),也不會拋出異常,而是當(dāng)線程池中的所有線程都被占用后,并且工作隊(duì)列被填滿后,下一個任務(wù)會在調(diào)用execute時在主線程中執(zhí)行,從而降低新任務(wù)的流量。由于執(zhí)行任務(wù)需要一定的時間,因此主線程至少在一定的時間內(nèi)不能提交任何任務(wù),從而使得工作者線程有時間來處理正在執(zhí)行的任務(wù)。
  • 另一方面,在這期間,主線程不會調(diào)用accept,那么到達(dá)的請求將被保存在TCP層的隊(duì)列中而不是在應(yīng)用程序的隊(duì)列中。如果持續(xù)過載,那么TCP層將最終發(fā)現(xiàn)他的請求隊(duì)列被填滿,因此同樣會開始拋棄請求。
  • 當(dāng)服務(wù)器過載時,這種過載情況會逐漸向外蔓延開來——從線程池到工作隊(duì)列到應(yīng)用程序再到TCP層,最終到達(dá)客戶端,導(dǎo)致服務(wù)器在高負(fù)載的情況下實(shí)現(xiàn)一種平緩的性能降低。


源碼如下:
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
? ? ? ? ? ? if (!e.isShutdown()) {
? ? ? ? ? ? ? ? //直接執(zhí)行run方法
? ? ? ? ? ? ? ? r.run();
? ? ? ? ? ? }
? ? ? ? }

自定義
如果以上策略都不符合業(yè)務(wù)場景,那么可以自己定義一個拒絕策略,只要實(shí)現(xiàn)RejectedExecutionHandler接口,并且實(shí)現(xiàn)rejectedExecution方法就可以了。具體的邏輯就在rejectedExecution方法里去定義就OK了。
例如:我定義了我的一個拒絕策略,叫做MyRejectPolicy,里面的邏輯就是打印處理被拒絕的任務(wù)內(nèi)容

public class MyRejectPolicy implements RejectedExecutionHandler{public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {//Sender是我的Runnable類,里面有message字段if (r instanceof Sender) {Sender sender = (Sender) r;//直接打印System.out.println(sender.getMessage());}} }

這幾種策略沒有好壞之分,只是適用不同場景,具體哪種合適根據(jù)具體場景和業(yè)務(wù)需要選擇,如果需要特殊處理就自己定義好了。

?

總結(jié)

以上是生活随笔為你收集整理的线程池的 RejectedExecutionHandler(拒绝策略)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。