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

@Scheduled注解不能同時(shí)執(zhí)行多個(gè)定時(shí)任務(wù)的解決方案

 更新時(shí)間:2022年09月30日 17:00:16   作者:程序員向陽  
這篇文章主要介紹了@Scheduled注解不能同時(shí)執(zhí)行多個(gè)定時(shí)任務(wù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

@Scheduled注解不能同時(shí)執(zhí)行多個(gè)定時(shí)任務(wù)

最近在使用定時(shí)任務(wù)的時(shí)候發(fā)現(xiàn),自己寫的定時(shí)任務(wù)沒有執(zhí)行,后來查了上網(wǎng)查了一下,才知道@Scheduled注解的定時(shí)任務(wù)是單線程的,同一時(shí)間段內(nèi)只能執(zhí)行一個(gè)定時(shí)任務(wù),其它定時(shí)任務(wù)不執(zhí)行。

需要配置@Scheduled多線程支持,才能實(shí)現(xiàn)同一時(shí)間段內(nèi),執(zhí)行多個(gè)定時(shí)任務(wù)。

一般情況下面兩個(gè)定時(shí)任務(wù)只會(huì)執(zhí)行第一個(gè)定時(shí)任務(wù),第二個(gè)定時(shí)任務(wù)不會(huì)執(zhí)行。

/**
? ? ?* 測試定時(shí)任務(wù)1 每天22:00:00執(zhí)行
? ? ?*/
? ? @Scheduled(cron = "0 0 22 * * ?")
? ? public void test() {
?
? ? ? ? for (int i = 0; i < 20; i++) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(1000 * 10);
? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println("=======================測試定時(shí)任務(wù)執(zhí)行1=======================");
? ? ? ? }
? ? }
?
? ? /**
? ? ?* 測試定時(shí)任務(wù)2 每天22:10:00執(zhí)行
? ? ?*/
? ? @Scheduled(cron = "0 10 22 * * ?")
? ? public void test2() {
?
? ? ? ? for (int i = 0; i < 20; i++) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(1000 * 10);
? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println("=======================測試定時(shí)任務(wù)執(zhí)行2=======================");
? ? ? ? }
? ? }

要解決上訴問題,就需要配置 @Scheduled多線程支持,添加一個(gè)配置類,代碼如下:

/**
?* @description: 使@schedule支持多線程的配置類
?* @author: David Allen
?* @create: 2020-12-08
?**/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
?
? ? @Override
? ? public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
?
? ? ? ? Method[] methods = Job.class.getMethods();
? ? ? ? int defaultPoolSize = 3;
? ? ? ? int corePoolSize = 0;
?
? ? ? ? if (!CollectionUtils.isEmpty(Arrays.asList(methods))) {
?
? ? ? ? ? ? for (Method method : methods) {
?
? ? ? ? ? ? ? ? Scheduled annotation = method.getAnnotation(Scheduled.class);
?
? ? ? ? ? ? ? ? if (annotation != null) {
?
? ? ? ? ? ? ? ? ? ? corePoolSize++;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (defaultPoolSize > corePoolSize) {
?
? ? ? ? ? ? ? ? corePoolSize = defaultPoolSize;
? ? ? ? ? ? }
?
? ? ? ? ? ? taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
? ? ? ? }
? ? }
}

@Scheduled同時(shí)執(zhí)行多個(gè)定時(shí)任務(wù)所導(dǎo)致的并發(fā)問題

@Scheduled的執(zhí)行順序

@Scheduled注解會(huì)在默認(rèn)情況下以單線程的方式執(zhí)行定時(shí)任務(wù)。

這個(gè)“單線程”指兩個(gè)方面:

  • 如果一個(gè)定時(shí)任務(wù)執(zhí)行時(shí)間大于其任務(wù)間隔時(shí)間,那么下一次將會(huì)等待上一次執(zhí)行結(jié)束后再繼續(xù)執(zhí)行。
  • 如果多個(gè)定時(shí)任務(wù)在同一時(shí)刻執(zhí)行,任務(wù)會(huì)依次執(zhí)行。

那么這種效果肯定不是我們想要的,為了使@Scheduled效率更高,我們可以通過兩種方法將定時(shí)任務(wù)變成多線程執(zhí)行:

1、在啟動(dòng)類中配置TaskScheduler線程池大小

@Bean
public TaskScheduler taskScheduler() {
?? ?ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
?? ?taskScheduler.setPoolSize(50);
?? ?return taskScheduler;
}

2、利用Spring提供的@Async注解和@EnableAsync注解

@Component
@EnableAsync
public class TimedTask{
? ? @Async
? ? @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執(zhí)行一次
? ? public void taskA() {
? ? ? ? //執(zhí)行你的業(yè)務(wù)邏輯
? ? }
? ??
? ? @Async
? ? @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執(zhí)行一次
? ? public void taskB() {
? ? ? ? //執(zhí)行你的業(yè)務(wù)邏輯
? ? }

通過以上方式,定時(shí)任務(wù)將會(huì)以多線程的方式開始執(zhí)行,減小了程序耦合度,提升運(yùn)行效率。

@Scheduled同步

定時(shí)任務(wù)在同一時(shí)刻開始執(zhí)行有兩種情況:

  • 多個(gè)任務(wù)的間隔時(shí)間相同,如都是1分鐘執(zhí)行一次,那么每一分鐘,這些任務(wù)都會(huì)一起執(zhí)行。
  • 多個(gè)任務(wù)的間隔時(shí)間不同,但有重合的時(shí)刻。如一個(gè)任務(wù)每天零點(diǎn)執(zhí)行,另一個(gè)任務(wù)每一分鐘執(zhí)行,那么這兩個(gè)任務(wù)在零點(diǎn)的時(shí)刻會(huì)一起執(zhí)行。

由于任務(wù)都是異步的,如果多個(gè)任務(wù)同時(shí)操作同一資源,那么必然會(huì)導(dǎo)致錯(cuò)誤。

這個(gè)時(shí)候可以給任務(wù)加鎖,保證任務(wù)互不干擾,擁有在同一時(shí)刻執(zhí)行的線程安全:

@Component
@EnableAsync
public class TimedTask{

?? ?private Object lock = new Object();
?? ?
? ? @Async
? ? @Scheduled(cron = "0 0 0 * * ?")//每天零點(diǎn)執(zhí)行
? ? public void taskA() {
? ? ?? ?synchronized(lock){
? ? ? ??? ??? ?//執(zhí)行你的業(yè)務(wù)邏輯
?? ??? ?}
? ? }
? ??
? ? @Async
? ? @Scheduled(cron = "0 0/1 * * * ?")//每一分鐘執(zhí)行一次
? ? public void taskB() {
? ? ?? ?synchronized(lock){
? ? ? ??? ??? ?//執(zhí)行你的業(yè)務(wù)邏輯
?? ??? ?}
? ? }

控制定時(shí)任務(wù)的執(zhí)行順序

如果對(duì)執(zhí)行順序有要求的定時(shí)任務(wù),有如下兩種情況:

1、在某一時(shí)刻同時(shí)執(zhí)行

如任務(wù)A在零點(diǎn)初始化數(shù)據(jù),任務(wù)B每分鐘更新數(shù)據(jù)。那么在零點(diǎn),必須是任務(wù)A先執(zhí)行,其次才是B。但加鎖只能保證線程安全,不能保證執(zhí)行順序。在這種情況下,我們可以借助redis設(shè)置獲取鎖的順序,亦或標(biāo)志字進(jìn)行執(zhí)行順序的判斷。

2、總是同時(shí)執(zhí)行

在任務(wù)間隔相同的情況下,一般為業(yè)務(wù)的解耦,不應(yīng)操作共享資源,應(yīng)當(dāng)放至同一個(gè)定時(shí)任務(wù)中執(zhí)行。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實(shí)現(xiàn)基于UDP協(xié)議的聊天小程序操作

    java實(shí)現(xiàn)基于UDP協(xié)議的聊天小程序操作

    UDP是與TCP相對(duì)應(yīng)的協(xié)議,UDP適用于一次只傳送少量數(shù)據(jù)、對(duì)可靠性要求不高的應(yīng)用環(huán)境。正因?yàn)閁DP協(xié)議沒有連接的過程,所以它的通信效率高;但也正因?yàn)槿绱耍目煽啃圆蝗鏣CP協(xié)議高,本文給大家介紹java實(shí)現(xiàn)基于UDP協(xié)議的聊天小程序操作,感興趣的朋友一起看看吧
    2021-10-10
  • Java編程偽共享與緩存行填充

    Java編程偽共享與緩存行填充

    這篇文章主要介紹了Java編程偽共享與緩存行填充,下面文章Disruptor提到的CPU緩存話題,做了一些嘗試和研究,如Disruptor所說,CPU有緩存?zhèn)喂蚕淼膯栴},并且通過緩存行填充能完美的解決這個(gè)問題,需要的朋友可以參考一下
    2021-09-09
  • Java引用隊(duì)列和虛引用實(shí)例分析

    Java引用隊(duì)列和虛引用實(shí)例分析

    這篇文章主要介紹了Java引用隊(duì)列和虛引用,結(jié)合實(shí)例形式分析了java引用隊(duì)列和虛引用相關(guān)概念、原理與使用方法,需要的朋友可以參考下
    2019-08-08
  • Spring中統(tǒng)一異常處理示例詳解

    Spring中統(tǒng)一異常處理示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring中統(tǒng)一異常處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • java實(shí)現(xiàn)郵件發(fā)送

    java實(shí)現(xiàn)郵件發(fā)送

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)郵件發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列示例介紹

    java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列示例介紹

    大家好,本篇文章主要講的是java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列示例介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Mybatis-Plus默認(rèn)主鍵策略導(dǎo)致自動(dòng)生成19位長度主鍵id的坑

    Mybatis-Plus默認(rèn)主鍵策略導(dǎo)致自動(dòng)生成19位長度主鍵id的坑

    這篇文章主要介紹了Mybatis-Plus默認(rèn)主鍵策略導(dǎo)致自動(dòng)生成19位長度主鍵id的坑,本文一步步給大家分享解決方法,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Java學(xué)習(xí)之緩沖流的原理詳解

    Java學(xué)習(xí)之緩沖流的原理詳解

    為了提高其數(shù)據(jù)的讀寫效率,Java中又定義了四種緩沖流,分別是:字節(jié)緩沖輸入流、字節(jié)緩沖輸出流、字符緩沖輸入流和字符緩沖輸出流。本文主要來和大家聊聊這些緩沖流的原理,希望對(duì)大家有所幫助
    2023-01-01
  • 一篇文章帶你入門java算術(shù)運(yùn)算符(加減乘除余,字符連接)

    一篇文章帶你入門java算術(shù)運(yùn)算符(加減乘除余,字符連接)

    這篇文章主要介紹了Java基本數(shù)據(jù)類型和運(yùn)算符,結(jié)合實(shí)例形式詳細(xì)分析了java基本數(shù)據(jù)類型、數(shù)據(jù)類型轉(zhuǎn)換、算術(shù)運(yùn)算符、邏輯運(yùn)算符等相關(guān)原理與操作技巧,需要的朋友可以參考下
    2021-08-08
  • mybatis-plus數(shù)據(jù)權(quán)限實(shí)現(xiàn)代碼

    mybatis-plus數(shù)據(jù)權(quán)限實(shí)現(xiàn)代碼

    這篇文章主要介紹了mybatis-plus數(shù)據(jù)權(quán)限實(shí)現(xiàn),結(jié)合了mybatis-plus的插件方式,做出了自己的注解方式的數(shù)據(jù)權(quán)限,雖然可能存在一部分的局限性,但很好的解決了我們自己去解析SQL的功能,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

民县| 嘉义市| 苗栗县| 泰州市| 利辛县| 塔城市| 中西区| 石狮市| 饶阳县| 鄂伦春自治旗| 华宁县| 班玛县| 遂平县| 保亭| 邮箱| 弋阳县| 关岭| 岳普湖县| 鲁山县| 延寿县| 高淳县| 志丹县| 宜昌市| 石泉县| 连山| 油尖旺区| 昔阳县| 宁德市| 滦平县| 佛教| 阿合奇县| 进贤县| 和林格尔县| 武山县| 离岛区| 岑巩县| 芦山县| 信阳市| 通许县| 宣恩县| 巴彦县|