亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring多定時(shí)任務(wù)@Scheduled執(zhí)行阻塞問(wèn)題解決

 更新時(shí)間:2022年05月26日 09:15:26   作者:LYM0721  
這篇文章主要介紹了Spring多定時(shí)任務(wù)@Scheduled執(zhí)行阻塞問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一. 問(wèn)題描述

最近項(xiàng)目中發(fā)現(xiàn)一個(gè)問(wèn)題,計(jì)劃每日凌晨4:40執(zhí)行一個(gè)定時(shí)任務(wù),使用注解方式: @Scheduled(cron = “0 40 4 * * ?”),cron表達(dá)式明顯沒(méi)有問(wèn)題,但是這個(gè)定時(shí)任務(wù)總是不按時(shí)執(zhí)行,有時(shí)候得等到8點(diǎn)多,有時(shí)候9點(diǎn)多才執(zhí)行。后來(lái)查了下,原來(lái)這種定時(shí)方式默認(rèn)是單線程執(zhí)行的,恰好我這里有多個(gè)定時(shí)任務(wù),并且其中有個(gè)在4:40之前的定時(shí)任務(wù)比較耗時(shí),導(dǎo)致4:40的任務(wù)只能等待之前的任務(wù)執(zhí)行完成才能夠觸發(fā),所以要自己手動(dòng)把定時(shí)任務(wù)設(shè)置成多線程的方式才行。

二. 場(chǎng)景復(fù)現(xiàn)

項(xiàng)目描述:使用Springboot進(jìn)行開(kāi)發(fā)
設(shè)置兩個(gè)定時(shí)任務(wù),每5s執(zhí)行一次,并打印出其執(zhí)行情況
代碼如下:

@Component
@Log4j2
public class ScheduledTask {
? ? @Scheduled(cron = "0/5 * * * * ?")
? ? public void task1() throws InterruptedException {
? ? ? ? log.info("I am task11111111, current thread: {}", Thread.currentThread());
? ? ? ? while (true) {
? ? ? ? ? ? //模擬耗時(shí)任務(wù),阻塞10s
? ? ? ? ? ? Thread.sleep(10000);
? ? ? ? ? ? break;
? ? ? ? }
? ? }

? ? @Scheduled(cron = "0/5 * * * * ?")
? ? public void task2() {
? ? ? ? log.info("I am task22222222, current thread: {}", Thread.currentThread());
? ? }
}

執(zhí)行結(jié)果如下:

2019-04-24 17:11:15.008  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:15.009  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:25.009  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:30.002  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:30.003  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[scheduling-1,5,main]
2019-04-24 17:11:40.004  INFO 16868 --- [   scheduling-1] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[scheduling-1,5,main]

由結(jié)果可見(jiàn),task1與task2由同一個(gè)線程Thread[scheduling-1,5,main]執(zhí)行,也即該定時(shí)任務(wù)默認(rèn)使用單線程,并且由于task1阻塞了10s,導(dǎo)致本應(yīng)5s執(zhí)行一次的定時(shí)任務(wù)10s才執(zhí)行一次。

三. 解決方案

網(wǎng)上有多種解決方案,以下列舉兩種

方案一:使用@Async注解實(shí)現(xiàn)異步任務(wù)

這種方式比較簡(jiǎn)單,在定時(shí)任務(wù)上加上@Async注解,注意:需啟動(dòng)類配合加上 @EnableAsync才會(huì)生效

代碼如下:

@Component
@Log4j2
public class ScheduledTask {
? ? @Async
? ? @Scheduled(cron = "0/5 * * * * ?")
? ? public void task1() throws InterruptedException {
? ? ? ? log.info("I am task11111111, current thread: {}", Thread.currentThread());
? ? ? ? while (true) {
? ? ? ? ? ? //模擬耗時(shí)任務(wù),阻塞10s
? ? ? ? ? ? Thread.sleep(10000);
? ? ? ? ? ? break;
? ? ? ? }
? ? }

? ? @Async
? ? @Scheduled(cron = "0/5 * * * * ?")
? ? public void task2() {
? ? ? ? log.info("I am task22222222, current thread: {}", Thread.currentThread());
? ? }
}

運(yùn)行結(jié)果:

2019-04-24 17:03:00.024  INFO 2152 --- [         task-1] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[task-1,5,main]
2019-04-24 17:03:00.024  INFO 2152 --- [         task-2] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[task-2,5,main]
2019-04-24 17:03:05.001  INFO 2152 --- [         task-3] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[task-3,5,main]
2019-04-24 17:03:05.001  INFO 2152 --- [         task-4] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[task-4,5,main]
2019-04-24 17:03:10.002  INFO 2152 --- [         task-5] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[task-5,5,main]
2019-04-24 17:03:10.003  INFO 2152 --- [         task-6] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[task-6,5,main]

由運(yùn)行日志可見(jiàn),定時(shí)每5s執(zhí)行一次已生效,且每次任務(wù)使用的線程不一樣,也即實(shí)現(xiàn)了多線程執(zhí)行定時(shí)任務(wù),不會(huì)出現(xiàn)任務(wù)等待現(xiàn)象。此方式據(jù)說(shuō)默認(rèn)線程池大小為100,要是任務(wù)不多的話有點(diǎn)大材小用了,所以我覺(jué)得第二種方式比較好。

方案二:手動(dòng)設(shè)置定時(shí)任務(wù)的線程池大小

定時(shí)任務(wù)代碼部分還原,不使用@Async注解,新增啟動(dòng)代碼配置:

@Configuration
public class AppConfig implements SchedulingConfigurer {
? ? @Bean
? ? public Executor taskExecutor() {
? ? ?? ?//指定定時(shí)任務(wù)線程數(shù)量,可根據(jù)需求自行調(diào)節(jié)
? ? ? ? return Executors.newScheduledThreadPool(3);
? ? }

? ? @Override
? ? public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
? ? ? ? scheduledTaskRegistrar.setScheduler(taskExecutor());
? ? }
}

運(yùn)行結(jié)果如下:

2019-04-24 17:26:15.008  INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:15.008  INFO 2164 --- [pool-1-thread-1] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[pool-1-thread-1,5,main]
2019-04-24 17:26:20.002  INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:25.001  INFO 2164 --- [pool-1-thread-2] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[pool-1-thread-2,5,main]
2019-04-24 17:26:30.001  INFO 2164 --- [pool-1-thread-1] com.example.demo.task.ScheduledTask      : I am task11111111, current thread: Thread[pool-1-thread-1,5,main]
2019-04-24 17:26:30.001  INFO 2164 --- [pool-1-thread-3] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[pool-1-thread-3,5,main]
2019-04-24 17:26:35.001  INFO 2164 --- [pool-1-thread-3] com.example.demo.task.ScheduledTask      : I am task22222222, current thread: Thread[pool-1-thread-3,5,main]

由結(jié)果可見(jiàn),第二種方式也實(shí)現(xiàn)了多線程任務(wù)調(diào)度。

四. 總結(jié)

 兩種方式各有優(yōu)缺點(diǎn):

比較方案一方案二
優(yōu)點(diǎn)注解方式使用簡(jiǎn)單,代碼量少配置靈活,線程數(shù)可控
缺點(diǎn)線程數(shù)不可控,可能存在資源浪費(fèi)需要增加編碼

留個(gè)坑,從日志上看@Async方式針對(duì)同一任務(wù)也是異步的,也即task1每5s會(huì)執(zhí)行一次,但是方式二貌似對(duì)同一個(gè)任務(wù)不會(huì)生效,task1執(zhí)行的時(shí)候需等待上一次執(zhí)行結(jié)束才會(huì)觸發(fā),并沒(méi)有每5s執(zhí)行一次。關(guān)于這個(gè)現(xiàn)象,下次再琢磨…

參考鏈接:https://segmentfault.com/a/1190000015267976

到此這篇關(guān)于Spring多定時(shí)任務(wù)@Scheduled執(zhí)行阻塞問(wèn)題解決的文章就介紹到這了,更多相關(guān)Spring多定時(shí)任務(wù)阻塞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java基于spring boot本地上傳圖片示例解析

    java基于spring boot本地上傳圖片示例解析

    這篇文章主要介紹了java基于spring boot本地上傳圖片示例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • JavaWeb之監(jiān)聽(tīng)器案例講解

    JavaWeb之監(jiān)聽(tīng)器案例講解

    這篇文章主要介紹了JavaWeb之監(jiān)聽(tīng)器案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java/Android 實(shí)現(xiàn)簡(jiǎn)單的HTTP服務(wù)器

    Java/Android 實(shí)現(xiàn)簡(jiǎn)單的HTTP服務(wù)器

    這篇文章主要介紹了Java/Android 如何實(shí)現(xiàn)簡(jiǎn)單的HTTP服務(wù)器,幫助大家更好的進(jìn)行功能測(cè)試,感興趣的朋友可以了解下
    2020-10-10
  • Java IO之字節(jié)輸入輸出流詳解

    Java IO之字節(jié)輸入輸出流詳解

    這篇文章主要為大家介紹了Java IO之字節(jié)輸入輸出流,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • Mybatis分頁(yè)P(yáng)ageHelper插件代碼實(shí)例

    Mybatis分頁(yè)P(yáng)ageHelper插件代碼實(shí)例

    這篇文章主要介紹了Mybatis分頁(yè)P(yáng)ageHelper插件代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 淺談SpringBoot之事務(wù)處理機(jī)制

    淺談SpringBoot之事務(wù)處理機(jī)制

    這篇文章主要介紹了淺談SpringBoot之事務(wù)處理機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn)

    Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn)

    本篇文章主要講述的是Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Maven+oracle+SSM搭建簡(jiǎn)單項(xiàng)目的方法

    Maven+oracle+SSM搭建簡(jiǎn)單項(xiàng)目的方法

    本篇文章主要介紹了Maven+oracle+SSM搭建簡(jiǎn)單項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • @Query注解的原生用法和native用法解析

    @Query注解的原生用法和native用法解析

    這篇文章主要介紹了@Query注解的原生用法和native用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java開(kāi)發(fā)BeanUtils類解決實(shí)體對(duì)象間賦值

    java開(kāi)發(fā)BeanUtils類解決實(shí)體對(duì)象間賦值

    這篇文章主要為大家介紹了java開(kāi)發(fā)中使用BeanUtils類實(shí)現(xiàn)實(shí)體對(duì)象之間的賦值有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步學(xué)有所得
    2021-10-10

最新評(píng)論