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

springboot為異步任務(wù)規(guī)劃自定義線程池的實(shí)現(xiàn)

 更新時(shí)間:2022年06月14日 08:33:40   作者:字母哥哥  
本文主要介紹了springboot為異步任務(wù)規(guī)劃自定義線程池,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、Spring Boot任務(wù)線程池

線程池的作用

  • 防止資源占用無限的擴(kuò)張
  • 調(diào)用過程省去資源的創(chuàng)建和銷毀所占用的時(shí)間

在高并發(fā)環(huán)境下,不斷的分配新資源,可能導(dǎo)致系統(tǒng)資源耗盡。所以為了避免這個(gè)問題,我們?yōu)楫惒饺蝿?wù)規(guī)劃一個(gè)線程池。當(dāng)然,如果沒有配置線程池的話,springboot會(huì)自動(dòng)配置一個(gè)ThreadPoolTaskExecutor 線程池到bean當(dāng)中。

# 核心線程數(shù)
spring.task.execution.pool.core-size=8  
# 最大線程數(shù)
spring.task.execution.pool.max-size=16
# 空閑線程存活時(shí)間
spring.task.execution.pool.keep-alive=60s
# 是否允許核心線程超時(shí)
spring.task.execution.pool.allow-core-thread-timeout=true
# 線程隊(duì)列數(shù)量
spring.task.execution.pool.queue-capacity=100
# 線程關(guān)閉等待
spring.task.execution.shutdown.await-termination=false
spring.task.execution.shutdown.await-termination-period=
# 線程名稱前綴
spring.task.execution.thread-name-prefix=task-

在springboot配置文件中加入上面的配置,即可實(shí)現(xiàn)ThreadPoolTaskExecutor 線程池。

二、自定義線程池

有的時(shí)候,我們希望將系統(tǒng)內(nèi)的一類任務(wù)放到一個(gè)線程池,另一類任務(wù)放到另外一個(gè)線程池,所以使用Spring Boot自帶的任務(wù)線程池就捉襟見肘了。下面介紹自定義線程池的方法。

創(chuàng)建一個(gè) 線程池配置類 TaskConfiguration ,并配置一個(gè) 任務(wù)線程池對象 taskExecutor。

@Configuration
public class TaskConfiguration {
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("taskExecutor-");
        executor.setRejectedExecutionHandler(new CallerRunsPolicy());
        return executor;
    }
}

上面我們通過使用 ThreadPoolTaskExecutor 創(chuàng)建了一個(gè) 線程池,同時(shí)設(shè)置了以下這些參數(shù):

線程池屬性屬性的作用上文代碼設(shè)置初始值
核心線程數(shù)CorePoolSize線程池創(chuàng)建時(shí)候初始化的線程數(shù),最小線程數(shù)10
最大線程數(shù)MaxPoolSize線程池最大的線程數(shù),只有在緩沖隊(duì)列滿了之后,才會(huì)申請超過核心線程數(shù)的線程20
緩沖任務(wù)隊(duì)列QueueCapacity用來緩沖執(zhí)行任務(wù)的隊(duì)列200
允許線程的空閑時(shí)間KeepAliveSeconds超過了核心線程之外的線程,在空閑時(shí)間到達(dá)之后,沒活干的線程會(huì)被銷毀60秒
線程池名的前綴 ThreadNamePrefix可以用于定位處理任務(wù)所在的線程池taskExecutor-
線程池對任務(wù)的Reject策略RejectedExecutionHandler當(dāng)線程池運(yùn)行飽和,或者線程池處于shutdown臨界狀態(tài)時(shí),用來拒絕一個(gè)任務(wù)的執(zhí)行CallerRunsPolicy

Reject策略預(yù)定義有四種:

  • AbortPolicy,用于被拒絕任務(wù)的處理程序,它將拋出RejectedExecutionException。
  • CallerRunsPolicy,用于被拒絕任務(wù)的處理程序,它直接在execute方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù)。
  • DiscardOldestPolicy,用于被拒絕任務(wù)的處理程序,它放棄最舊的未處理請求,然后重試execute。
  • DiscardPolicy,用于被拒絕任務(wù)的處理程序,默認(rèn)情況下它將丟棄被拒絕的任務(wù)。

創(chuàng)建 AsyncExecutorTask類,三個(gè)任務(wù)的配置和 AsyncTask 一樣,不同的是 @Async 注解需要指定前面配置的 線程池的名稱 taskExecutor。

@Component
public class AsyncExecutorTask extends AbstractTask {
? ? @Async("taskExecutor")
? ? public Future<String> doTaskOneCallback() throws Exception {
? ? ? ? super.doTaskOne();
? ? ? ? System.out.println("任務(wù)一,當(dāng)前線程:" + Thread.currentThread().getName());
? ? ? ? return new AsyncResult<>("任務(wù)一完成");
? ? }

? ? @Async("taskExecutor")
? ? public Future<String> doTaskTwoCallback() throws Exception {
? ? ? ? super.doTaskTwo();
? ? ? ? System.out.println("任務(wù)二,當(dāng)前線程:" + Thread.currentThread().getName());
? ? ? ? return new AsyncResult<>("任務(wù)二完成");
? ? }

? ? @Async("taskExecutor")
? ? public Future<String> doTaskThreeCallback() throws Exception {
? ? ? ? super.doTaskThree();
? ? ? ? System.out.println("任務(wù)三,當(dāng)前線程:" + Thread.currentThread().getName());
? ? ? ? return new AsyncResult<>("任務(wù)三完成");
? ? }
}

在 單元測試 用例中,注入 AsyncExecutorTask 對象,并在測試用例中執(zhí)行 doTaskOne(),doTaskTwo(),doTaskThree() 三個(gè)方法。

@SpringBootTest
public class AsyncExecutorTaskTest {
? ? @Autowired
? ? private AsyncExecutorTask task;

? ? @Test
? ? public void testAsyncExecutorTask() throws Exception {
? ? ? ? task.doTaskOneCallback();
? ? ? ? task.doTaskTwoCallback();
? ? ? ? task.doTaskThreeCallback();

? ? ? ? sleep(30 * 1000L);
? ? }
}

執(zhí)行一下上述的 單元測試,可以看到如下結(jié)果:

開始做任務(wù)一
開始做任務(wù)三
開始做任務(wù)二
完成任務(wù)二,耗時(shí):3905毫秒
任務(wù)二,當(dāng)前線程:taskExecutor-2
完成任務(wù)一,耗時(shí):6184毫秒
任務(wù)一,當(dāng)前線程:taskExecutor-1
完成任務(wù)三,耗時(shí):9737毫秒
任務(wù)三,當(dāng)前線程:taskExecutor-3

執(zhí)行上面的單元測試,觀察到 任務(wù)線程池 的 線程池名的前綴 被打印,說明 線程池 成功執(zhí)行 異步任務(wù)!

三、優(yōu)雅地關(guān)閉線程池

由于在應(yīng)用關(guān)閉的時(shí)候異步任務(wù)還在執(zhí)行,導(dǎo)致類似 數(shù)據(jù)庫連接池 這樣的對象一并被 銷毀了,當(dāng) 異步任務(wù) 中對 數(shù)據(jù)庫 進(jìn)行操作就會(huì)出錯(cuò)。

解決方案如下,重新設(shè)置線程池配置對象,新增線程池 setWaitForTasksToCompleteOnShutdown() 和 setAwaitTerminationSeconds() 配置:

@Bean("taskExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
    executor.setPoolSize(20);
    executor.setThreadNamePrefix("taskExecutor-");
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.setAwaitTerminationSeconds(60);
    return executor;
}
  • setWaitForTasksToCompleteOnShutdown(true): 該方法用來設(shè)置 線程池關(guān)閉 的時(shí)候 等待 所有任務(wù)都完成后,再繼續(xù) 銷毀 其他的 Bean,這樣這些 異步任務(wù) 的 銷毀 就會(huì)先于 數(shù)據(jù)庫連接池對象 的銷毀。
  • setAwaitTerminationSeconds(60): 該方法用來設(shè)置線程池中 任務(wù)的等待時(shí)間,如果超過這個(gè)時(shí)間還沒有銷毀就 強(qiáng)制銷毀,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住。

異步任務(wù)** 的 銷毀 就會(huì)先于 數(shù)據(jù)庫連接池對象 的銷毀。

  • setAwaitTerminationSeconds(60): 該方法用來設(shè)置線程池中 任務(wù)的等待時(shí)間,如果超過這個(gè)時(shí)間還沒有銷毀就 強(qiáng)制銷毀,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住。

 到此這篇關(guān)于springboot為異步任務(wù)規(guī)劃自定義線程池的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot異步自定義線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA啟動(dòng)Tomcat時(shí)控制臺出現(xiàn)亂碼問題及解決

    IDEA啟動(dòng)Tomcat時(shí)控制臺出現(xiàn)亂碼問題及解決

    這篇文章主要介紹了IDEA啟動(dòng)Tomcat時(shí)控制臺出現(xiàn)亂碼問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Java字符串駝峰與下?lián)Q線格式轉(zhuǎn)換如何實(shí)現(xiàn)

    Java字符串駝峰與下?lián)Q線格式轉(zhuǎn)換如何實(shí)現(xiàn)

    這篇文章主要介紹了Java字符串駝峰與下?lián)Q線格式轉(zhuǎn)換如何實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java 方法重寫與權(quán)限修飾符以及多態(tài)和抽象類詳解概念和用法

    java 方法重寫與權(quán)限修飾符以及多態(tài)和抽象類詳解概念和用法

    重寫是子類對父類的允許訪問的方法的實(shí)現(xiàn)過程進(jìn)行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫,權(quán)限修飾符用于控制被修飾變量、方法、類的可見范圍,說明了面向?qū)ο蟮姆庋b性,所以我們要適用他們盡可能的讓權(quán)限降到最低,從而安全性提高
    2021-10-10
  • Mybatis-Plus支持GBase8s分頁查詢的實(shí)現(xiàn)示例

    Mybatis-Plus支持GBase8s分頁查詢的實(shí)現(xiàn)示例

    本文主要介紹了使?Mybatis-Plus?支持?GBase8s?的分頁查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • JAVA十大排序算法之基數(shù)排序詳解

    JAVA十大排序算法之基數(shù)排序詳解

    這篇文章主要介紹了java中的基數(shù)排序,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • springboot中的starter使用解析

    springboot中的starter使用解析

    這篇文章主要介紹了springboot中的starter使用解析,引入了starter依賴之后,基礎(chǔ)組件就可以像在spring的bean一樣在項(xiàng)目中使用,那其實(shí)只要找到在哪里加載了這些bean就明白了,需要的朋友可以參考下
    2023-10-10
  • SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案

    SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案

    在Spring Cloud 中微服務(wù)之間的調(diào)用會(huì)用到Feign,但是在默認(rèn)情況下,Feign 調(diào)用遠(yuǎn)程服務(wù)存在Header請求頭丟失問題,下面給大家分享SpringCloud微服務(wù)調(diào)用丟失請求頭的問題及解決方案,感興趣的朋友一起看看吧
    2024-02-02
  • Java設(shè)計(jì)模式之裝飾模式詳解

    Java設(shè)計(jì)模式之裝飾模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式中的裝飾者模式,裝飾者模式即Decorator Pattern,裝飾模式是在不必改變原類文件和使用繼承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對象的功能,裝飾模式又名包裝模式。裝飾器模式以對客戶端透明的方式拓展對象的功能,是繼承關(guān)系的一種替代方案
    2022-08-08
  • Java開發(fā)工具-scala處理json格式利器-json4s詳解

    Java開發(fā)工具-scala處理json格式利器-json4s詳解

    這篇文章主要介紹了開發(fā)工具-scala處理json格式利器-json4s,文章中處理方法講解的很清楚,有需要的同學(xué)可以研究下
    2021-02-02
  • Java基于裝飾者模式實(shí)現(xiàn)的染色饅頭案例詳解

    Java基于裝飾者模式實(shí)現(xiàn)的染色饅頭案例詳解

    這篇文章主要介紹了Java基于裝飾者模式實(shí)現(xiàn)的染色饅頭案例,簡單描述了裝飾者模式的概念、原理及Java使用裝飾者模式的相關(guān)實(shí)現(xiàn)步驟、操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-05-05

最新評論