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

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

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

一. 問題描述

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

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

項目描述:使用Springboot進行開發(fā)
設(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) {
? ? ? ? ? ? //模擬耗時任務(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é)果可見,task1與task2由同一個線程Thread[scheduling-1,5,main]執(zhí)行,也即該定時任務(wù)默認使用單線程,并且由于task1阻塞了10s,導(dǎo)致本應(yīng)5s執(zhí)行一次的定時任務(wù)10s才執(zhí)行一次。

三. 解決方案

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

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

這種方式比較簡單,在定時任務(wù)上加上@Async注解,注意:需啟動類配合加上 @EnableAsync才會生效

代碼如下:

@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) {
? ? ? ? ? ? //模擬耗時任務(wù),阻塞10s
? ? ? ? ? ? Thread.sleep(10000);
? ? ? ? ? ? break;
? ? ? ? }
? ? }

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

運行結(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]

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

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

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

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

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

運行結(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é)果可見,第二種方式也實現(xiàn)了多線程任務(wù)調(diào)度。

四. 總結(jié)

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

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

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

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

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

相關(guān)文章

  • 淺談spring aop的五種通知類型

    淺談spring aop的五種通知類型

    這篇文章主要介紹了淺談spring aop的五種通知類型,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • logback ThresholdFilter臨界值日志過濾器源碼解讀

    logback ThresholdFilter臨界值日志過濾器源碼解讀

    這篇文章主要為大家介紹了logback ThresholdFilter臨界值日志過濾器源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Spring?注入靜態(tài)對象使用三種方式示例

    Spring?注入靜態(tài)對象使用三種方式示例

    這篇文章主要為大家介紹了Spring注入靜態(tài)對象使用的三種方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • 解決spirngboot連接redis報錯:READONLY?You?can‘t?write?against?a?read?only?replica的問題

    解決spirngboot連接redis報錯:READONLY?You?can‘t?write?against?

    docker部署的redis,springboot基本每天來連redis都報錯:READONLY?You?can't?write?against?a?read?only?replica,重啟redis后,可以正常連接。但是每天都重啟redis,不現(xiàn)實,也很麻煩,今天給大家分享解決方式,感興趣的朋友一起看看吧
    2023-06-06
  • elasticsearch索引index之Mapping實現(xiàn)關(guān)系結(jié)構(gòu)示例

    elasticsearch索引index之Mapping實現(xiàn)關(guān)系結(jié)構(gòu)示例

    這篇文章主要介紹了elasticsearch索引index之Mapping實現(xiàn)關(guān)系結(jié)構(gòu)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • 一文帶你搞懂Java類加載機制

    一文帶你搞懂Java類加載機制

    Java?類加載機制是?Java?運行時的核心組成部分,負責(zé)在程序運行過程中動態(tài)加載和連接類文件,并將其轉(zhuǎn)換為可執(zhí)行代碼,接下來小編就來帶大家搞懂面試官老問的?Java?類加載機制,需要的朋友可以參考下
    2023-08-08
  • Spring?Boot實現(xiàn)JWT?token自動續(xù)期的實現(xiàn)

    Spring?Boot實現(xiàn)JWT?token自動續(xù)期的實現(xiàn)

    本文主要介紹了Spring?Boot實現(xiàn)JWT?token自動續(xù)期,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 詳解Java集合類之Map篇

    詳解Java集合類之Map篇

    這篇文章主要為大家詳細介紹一下Java集合類中Map的用法,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java有一定幫助,感興趣的可以了解一下
    2022-07-07
  • Java CAS原子操作詳解

    Java CAS原子操作詳解

    在synchronized的優(yōu)化過程中我們看到大量使用了CAS操作,CAS全稱Compare And Set(或Compare And Swap),簡單來說CAS操作就是一個虛擬機實現(xiàn)的原子操作
    2023-02-02
  • 基于Struts2實現(xiàn)防止表單重復(fù)提交

    基于Struts2實現(xiàn)防止表單重復(fù)提交

    這篇文章主要介紹了基于Struts2實現(xiàn)防止表單重復(fù)提交,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10

最新評論

辉县市| 黎川县| 临夏县| 资阳市| 万源市| 连州市| 张家界市| 尚志市| 喜德县| 东山县| 夏河县| 长垣县| 随州市| 奎屯市| 和林格尔县| 固镇县| 灵丘县| 景宁| 扬中市| 桦甸市| 潞西市| 二手房| 达拉特旗| 盐源县| 沁阳市| 舒城县| 尼玛县| 栖霞市| 尼木县| 西和县| 民乐县| 布拖县| 邵东县| 海安县| 湖北省| 木里| 油尖旺区| 通辽市| 沈丘县| 炎陵县| 曲麻莱县|