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

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

 更新時(shí)間:2022年09月30日 17:00:16   作者:程序員向陽  
這篇文章主要介紹了@Scheduled注解不能同時(shí)執(zhí)行多個(gè)定時(shí)任務(wù)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(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í)行順序

如果對執(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中return的用法(兩種)

    Java中return的用法(兩種)

    這篇文章主要介紹了Java中return的用法(兩種)的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • 深入了解MyBatis參數(shù)

    深入了解MyBatis參數(shù)

    今天小編就為大家分享一篇關(guān)于深入了解MyBatis參數(shù),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • SpringBoot全局異常處理機(jī)制和配置攔截器方式

    SpringBoot全局異常處理機(jī)制和配置攔截器方式

    這篇文章主要介紹了SpringBoot全局異常處理機(jī)制和配置攔截器方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java之左旋轉(zhuǎn)字符串介紹

    java之左旋轉(zhuǎn)字符串介紹

    java之左旋轉(zhuǎn)字符串介紹,需要的朋友可以參考一下
    2013-02-02
  • 解決mybatis-plus3.4.1分頁插件PaginationInterceptor和防止全表更新與刪除插件SqlExplainInterceptor過時(shí)失效問題

    解決mybatis-plus3.4.1分頁插件PaginationInterceptor和防止全表更新與刪除插件SqlE

    這篇文章給大家介紹了在Spring.xml文件中配置mybatis-plus3.4.1分頁插件PaginationInterceptor和防止全表更新與刪除插件SqlExplainInterceptor過時(shí)失效問題解決方案,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-12-12
  • 學(xué)會(huì)IDEA REST Client后就可以丟掉postman了

    學(xué)會(huì)IDEA REST Client后就可以丟掉postman了

    這篇文章主要介紹了學(xué)會(huì)IDEA REST Client后就可以丟掉postman了,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • @ConfigurationProperties在IDEA中出現(xiàn)紅色波浪線問題解決方法

    @ConfigurationProperties在IDEA中出現(xiàn)紅色波浪線問題解決方法

    本文介紹了在Springboot項(xiàng)目中,當(dāng)@ConfigurationProperties注解出現(xiàn)紅色波浪線時(shí)的解決方法,文中有詳細(xì)的解決方案供大家參考,需要的朋友可以參考下
    2024-09-09
  • Java SPEL表達(dá)式注入漏洞原理解析

    Java SPEL表達(dá)式注入漏洞原理解析

    SpEL簡稱Spring表達(dá)式語言,在Spring 3中引入,SpEL能在運(yùn)行時(shí)構(gòu)建復(fù)雜表達(dá)式、存取對象圖屬性、對象方法調(diào)用等等,可以與基于XML和基于注解的Spring配置還有bean定義一起使用,本文給大家介紹Java SPEL表達(dá)式注入漏洞原理研究,感興趣的朋友一起看看吧
    2023-10-10
  • Java并發(fā)編程之Fork/Join框架的理解

    Java并發(fā)編程之Fork/Join框架的理解

    今天帶大家學(xué)習(xí)Java并發(fā)編程的相關(guān)知識(shí),文中對Fork/Join框架作了非常詳細(xì)的介紹,對正在學(xué)習(xí)有關(guān)知識(shí)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-06-06
  • springboot下添加全局異常處理和自定義異常處理的過程解析

    springboot下添加全局異常處理和自定義異常處理的過程解析

    在spring項(xiàng)目中,優(yōu)雅處理異常,好處是可以將系統(tǒng)產(chǎn)生的全部異常統(tǒng)一捕獲處理,自定義的異常也由全局異常來捕獲,如果涉及到validator參數(shù)校驗(yàn)器使用全局異常捕獲也是較為方便,這篇文章主要介紹了springboot下添加全局異常處理和自定義異常處理,需要的朋友可以參考下
    2023-12-12

最新評論