最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

線程池的作用

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

在高并發(fā)環(huán)境下,不斷的分配新資源,可能導(dǎo)致系統(tǒng)資源耗盡。所以為了避免這個(gè)問(wèn)題,我們?yōu)楫惒饺蝿?wù)規(guī)劃一個(gè)線程池。當(dāng)然,如果沒(méi)有配置線程池的話,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)的一類(lèi)任務(wù)放到一個(gè)線程池,另一類(lèi)任務(wù)放到另外一個(gè)線程池,所以使用Spring Boot自帶的任務(wù)線程池就捉襟見(jiàn)肘了。下面介紹自定義線程池的方法。

創(chuàng)建一個(gè) 線程池配置類(lèi) TaskConfiguration ,并配置一個(gè) 任務(wù)線程池對(duì)象 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;
    }
}

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

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

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

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

創(chuàng)建 AsyncExecutorTask類(lèi),三個(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ù)三完成");
? ? }
}

在 單元測(cè)試 用例中,注入 AsyncExecutorTask 對(duì)象,并在測(cè)試用例中執(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í)行一下上述的 單元測(cè)試,可以看到如下結(jié)果:

開(kāi)始做任務(wù)一
開(kāi)始做任務(wù)三
開(kāi)始做任務(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í)行上面的單元測(cè)試,觀察到 任務(wù)線程池 的 線程池名的前綴 被打印,說(shuō)明 線程池 成功執(zhí)行 異步任務(wù)!

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

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

解決方案如下,重新設(shè)置線程池配置對(duì)象,新增線程池 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): 該方法用來(lái)設(shè)置 線程池關(guān)閉 的時(shí)候 等待 所有任務(wù)都完成后,再繼續(xù) 銷(xiāo)毀 其他的 Bean,這樣這些 異步任務(wù) 的 銷(xiāo)毀 就會(huì)先于 數(shù)據(jù)庫(kù)連接池對(duì)象 的銷(xiāo)毀。
  • setAwaitTerminationSeconds(60): 該方法用來(lái)設(shè)置線程池中 任務(wù)的等待時(shí)間,如果超過(guò)這個(gè)時(shí)間還沒(méi)有銷(xiāo)毀就 強(qiáng)制銷(xiāo)毀,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住。

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

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

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

相關(guān)文章

  • 深入淺出MyBatis中映射文件和實(shí)體類(lèi)的關(guān)聯(lián)性

    深入淺出MyBatis中映射文件和實(shí)體類(lèi)的關(guān)聯(lián)性

    這篇文章主要介紹了MyBatis中映射文件和實(shí)體類(lèi)的關(guān)聯(lián)性的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • 淺談為什么Java中1000==1000為false而100==100為true

    淺談為什么Java中1000==1000為false而100==100為true

    這篇文章主要介紹了淺談為什么Java中1000==1000為false而100==100為true,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 基于自定義校驗(yàn)注解(controller、method、(groups)分組的使用)

    基于自定義校驗(yàn)注解(controller、method、(groups)分組的使用)

    這篇文章主要介紹了基于自定義校驗(yàn)注解(controller、method、(groups)分組的使用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java對(duì)List進(jìn)行排序的方法總結(jié)

    Java對(duì)List進(jìn)行排序的方法總結(jié)

    在Java中,對(duì)List進(jìn)行排序是一項(xiàng)常見(jiàn)的任務(wù),Java提供了多種方法來(lái)對(duì)List中的元素進(jìn)行排序,本文將詳細(xì)介紹如何使用Java來(lái)實(shí)現(xiàn)List的排序操作,涵蓋了常用的排序方法和技巧,需要的朋友可以參考下
    2024-07-07
  • java 中 ChannelHandler的用法詳解

    java 中 ChannelHandler的用法詳解

    這篇文章主要介紹了java 中 ChannelHandler的用法詳解的相關(guān)資料,ChannelHandler處理一個(gè)I/O event或者攔截一個(gè)I/O操作,需要的朋友可以參考下
    2017-08-08
  • 自定義注解實(shí)現(xiàn)Spring容器注入Bean方式(類(lèi)似于mybatis的@MapperScans)

    自定義注解實(shí)現(xiàn)Spring容器注入Bean方式(類(lèi)似于mybatis的@MapperScans)

    本文介紹了如何通過(guò)自定義注解@MyService和@MyServiceScans在SpringBoot項(xiàng)目中自動(dòng)將指定包下的類(lèi)注入Spring容器,詳細(xì)解釋了創(chuàng)建自定義注解、定義包掃描器ClassPathBeanDefinitionScanner的作用與實(shí)現(xiàn)
    2024-09-09
  • java類(lèi)加載器和類(lèi)反射使用示例

    java類(lèi)加載器和類(lèi)反射使用示例

    這篇文章主要介紹了java類(lèi)加載器和類(lèi)反射使用示例,需要的朋友可以參考下
    2014-03-03
  • idea遠(yuǎn)程Debug部署在服務(wù)器上的服務(wù)

    idea遠(yuǎn)程Debug部署在服務(wù)器上的服務(wù)

    在開(kāi)發(fā)的時(shí)候我們通常在本地代碼上debug程序,但是服務(wù)部署到了開(kāi)發(fā)環(huán)境服務(wù)器上,如何遠(yuǎn)程調(diào)試,本文主要介紹了idea遠(yuǎn)程Debug部署在服務(wù)器上的服務(wù),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Calcite使用SQL實(shí)現(xiàn)查詢excel內(nèi)容

    Calcite使用SQL實(shí)現(xiàn)查詢excel內(nèi)容

    因?yàn)閏alcite本身沒(méi)有excel的適配器,?所以本文將模仿calcite-file,?搞一個(gè)calcite-file-excel實(shí)現(xiàn)查詢excel內(nèi)容,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-01-01
  • SpringBoot實(shí)用小技巧之如何動(dòng)態(tài)設(shè)置日志級(jí)別

    SpringBoot實(shí)用小技巧之如何動(dòng)態(tài)設(shè)置日志級(jí)別

    這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)用小技巧之如何動(dòng)態(tài)設(shè)置日志級(jí)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論

安化县| 黄冈市| 运城市| 建平县| 独山县| 永昌县| 宕昌县| 怀柔区| 虞城县| 大渡口区| 应用必备| 开江县| 贺州市| 嵊泗县| 九龙坡区| 洛隆县| 嘉兴市| 合山市| 墨竹工卡县| 龙陵县| 娄底市| 广水市| 嫩江县| 昭苏县| 隆尧县| 张家港市| 河东区| 中山市| 阜城县| 黑水县| 四平市| 远安县| 富顺县| 时尚| 新龙县| 泽库县| 富宁县| 乌兰县| 榆树市| 井冈山市| 西藏|