欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程池的拒絕策略實現(xiàn)詳解

 更新時間:2019年09月25日 15:06:34   作者:阿呆很呆非常呆  
這篇文章主要介紹了Java線程池的拒絕策略實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

一、簡介

jdk1.5 版本新增了JUC并發(fā)編程包,大大的簡化了傳統(tǒng)的多線程開發(fā)。

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

既然是池子,那么必然的會存在最大值、初始值以及存活值等屬性。在達到某些特定條件的時候,再來請求的話,池子是如何進行請求處理的呢?這里就引出了池的拒絕策略。一般的數(shù)據(jù)庫連接池在達到最大連接數(shù)的時候會默認的等待特定的設置的時間或者直接就拋出異常。而本文中要闡述的線程池卻并非如此的策略,下面開始展開講解下。

二、線程池的拒絕策略

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

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

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

三、拒絕策略定義

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

jdk默認提供了四種拒絕策略:CallerRunsPolicy - 當觸發(fā)拒絕策略,只要線程池沒有關閉的話,則使用調用線程直接運行任務。

一般并發(fā)比較小,性能要求不高,不允許失敗。但是,由于調用者自己運行任務,如果任務提交速度過快,可能導致程序阻塞,性能效率上必然的損失較大

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

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

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

四、測試代碼

1、AbortPolicy

package com.cfang;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class T2 {
 public static void main(String[] args) throws Exception{
  int corePoolSize = 5;
  int maximumPoolSize = 10;
  long keepAliveTime = 5;
  BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
  RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
  ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
  for(int i=0; i<100; i++) {
   try {
    executor.execute(new Thread(() -> log.info(Thread.currentThread().getName() + " is running")));
   } catch (Exception e) {
    log.error(e.getMessage());
   }
  }
  executor.shutdown();
 }
}

如果 executor.execute()提交任務,由于會拋出 RuntimeException,沒有try.catch處理異常信息的話,會中斷調用者的處理流程,后續(xù)任務得不到執(zhí)行(跑不完100個)??勺孕袦y試下。

2、CallerRunsPolicy

主體代碼同上,更換拒絕策略:

RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

運行后,在控制臺console中能夠看到的是,會有一部分的數(shù)據(jù)打印,顯示的是 “main is running”,也即體現(xiàn)調用線程處理。

3、DiscardPolicy

更換拒絕策略

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

直接丟棄任務,實際運行中,打印出的信息不會有100條。

4、DiscardOldestPolicy

同樣的,更換拒絕策略:

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();

實際運行,打印出的信息也會少于100條。

五、總結

四種拒絕策略是相互獨立無關的,選擇何種策略去執(zhí)行,還得結合具體的業(yè)務場景。實際工作中,一般直接使用 ExecutorService 的時候,都是使用的默認的 defaultHandler ,也即 AbortPolicy 策略。

相關文章

  • 構建SpringBoot+MyBatis+Freemarker的項目詳解

    構建SpringBoot+MyBatis+Freemarker的項目詳解

    在本篇內容里小編給大家整理的是關于構建SpringBoot+MyBatis+Freemarker的項目的具體步驟以及實例代碼,需要的朋友們參考下。
    2019-06-06
  • SpringBoot之自定義啟動異常堆棧信息打印方式

    SpringBoot之自定義啟動異常堆棧信息打印方式

    這篇文章主要介紹了SpringBoot之自定義啟動異常堆棧信息打印方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot2實現(xiàn)MessageQueue消息隊列

    SpringBoot2實現(xiàn)MessageQueue消息隊列

    本文主要介紹了 SpringBoot2實現(xiàn)MessageQueue消息隊列,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 詳解MybatisPlus中@Version注解的使用

    詳解MybatisPlus中@Version注解的使用

    在MyBatisPlus中,常常使用@Version實現(xiàn)樂觀鎖,該注解用于字段上面。本文將通過示例詳細講解@Version注解的使用,感興趣的可以了解一下
    2022-06-06
  • SpringFox實現(xiàn)自動生成RESTful?API文檔

    SpringFox實現(xiàn)自動生成RESTful?API文檔

    在開發(fā)?RESTful?API?時,編寫?API?文檔是一個重要的任務,這篇文章為大家介紹了如何使用?SpringFox?自動生成?RESTful?API?文檔,并提供示例代碼,需要的可以參考一下
    2023-06-06
  • Java 常量池的實例詳解

    Java 常量池的實例詳解

    這篇文章主要介紹了Java 常量池的實例詳解的相關資料,Java的常量池中包含了類、接口、方法、字符串等一系列常量值,需要的朋友可以參考下
    2017-09-09
  • Java過濾器如何解決存儲型xss攻擊問題

    Java過濾器如何解決存儲型xss攻擊問題

    這篇文章主要介紹了Java過濾器如何解決存儲型xss攻擊問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 如何用SpringBoot 進行測試

    如何用SpringBoot 進行測試

    這篇文章主要介紹了如何用SpringBoot 進行測試,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • SpringBoot + JPA @ManyToMany的操作要點說明

    SpringBoot + JPA @ManyToMany的操作要點說明

    這篇文章主要介紹了SpringBoot + JPA @ManyToMany的操作要點說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot 工程中的異常處理方式

    SpringBoot 工程中的異常處理方式

    這篇文章主要介紹了SpringBoot 工程中的異常處理方式,幫助大家更好的理解和學習使用springboot框架,感興趣的朋友可以了解下
    2021-02-02

最新評論