一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 使用springboot時,解決@Scheduled定時器遇到的問題

使用springboot時,解決@Scheduled定時器遇到的問題

2022-03-08 14:00teng_sd_cn Java教程

這篇文章主要介紹了使用springboot時,解決@Scheduled定時器遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

@Scheduled定時器遇到的問題

@Scheduled 這個注解確實給我們帶了很大的方便,我們只要加上該注解,并且根據需求設置好就可以使用定時任務了。

但是,我們需要注意的是,@Scheduled 并不一定一定會按時執行。

因為使用@Scheduled 的定時任務雖然是異步執行的,但是,不同的定時任務之間并不是并行的!!!!!!!!

在其中一個定時任務沒有執行完之前,其他的定時任務即使是到了執行時間,也是不會執行的,它們會進行排隊。

也就是如果你想你不同的定時任務互不影響,到時間就會執行,那么你最好將你的定時任務方法自己搞成異步方法,這樣,

定時任務其實就相當于調用了一個線程執行任務,一瞬間就結束了。當然,也可以勉強當做是任務都會定時執行。

下面說一下@Scheduled 注解的幾個參數

一、可以通過配置文件配置進來的

使用表達式,該表達式表示每一秒中執行一次。如果上一次方法超過了定時時間還沒有執行完,那么下一次定時不會執行,

直到上次方法執行完后,就會立即執行下一次的定時任務

該方式在工程啟動的時候,并不會立即執行,會按照定時表達式的規律進行執行。例如這里,就是1秒后才會執行。

?
1
@Scheduled(cron="0/1 * * * * ?")

使用固定速率。該表達式表示每隔一秒鐘執行一次。如果上一次方法超過了1秒鐘還沒執行完,下一次任務也不會執行,直到

上次方法執行完,下次的定時就會立即執行。

該方式在工程啟動的時候,會立即執行,接下來會按規律進行執行。

?
1
@Scheduled(fixedRateString="1000")   // 單位:毫秒

該方式和上一個的不同在于多加了一個參數,這個參數是一個初始化參數。

加上initialDelayString后,在剛啟動的時候,就不會立即執行了,而是會等到10秒之后才會執行,即使fixedRateString才

1秒鐘。也會在10秒后才會第一次執行。

注意:initialDelayString不能喝cron組合使用。

?
1
@Scheduled(fixedRateString="1000",initialDelayString="10000")

使用固定延遲。該表達式表示每次執行完后一秒再次執行。每一次執行,無論執行多長時間,下一次執行都會在上一次方法

執行完后,再過一秒鐘,再次執行。

該方式在工程啟動的時候,會立即執行,接下來會按規律進行執行。

?
1
@Scheduled(fixedDelayString="1000")

二、不可通過配置文件配置的 (作用相同)

?
1
2
3
@Scheduled(fixedRate=1000)      // 它們都是接受一個long類型的參數
@Scheduled(fixedDelay=1000)
@Scheduled(fixedRate=1000,initialDelay=10000)

這里粘貼一下cron表達式的規則:

字段 允許值 允許的特殊字符
0-59 , - * /
小時 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可選) 留空, 1970-2099 , - * /

定時任務@Scheduled使用的那些坑

@Scheduled是spring自帶的注解,默認是單線程,常用作定時任務使用,但是如果是集群版的機器的話,就考慮加上分布式鎖或者使用分布式定時任務代替。

一、使用的那些坑?

1.單線程

因為@Scheduled默認使用的是單線程,如果有兩個任務A和B,那么任務A要是阻塞了,任務B就無法執行。

2.@Async和@EnableAsync

為了解決單線程帶來的線程阻塞問題,我們可以使用@Async和@EnableAsync兩個注解采用異步的方式去處理,這樣就是不同的線程去執行,但是這種方式也帶來一個新的問題,那就是如果任務A的任務執行時間>任務調度周期時間的話,就會發生上一個任務未執行完畢,下一個任務又開始執行的邏輯,這種也是有風險的。所以最好使用多線程方式,自己控制線程池的數量,線程名稱等。

二、使用多線程

需要實現SchedulingConfigurer接口,然后自定義線程池,這樣凡是用到@Scheduled注解的都可以用該線程池,同時也解決了上述比較坑的兩個問題。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
    @Bean
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(20, (Runnable r) -> {
            Thread thread = new Thread(r);
            thread.setName("自定義線程名稱");
            return thread;
        });
    }
}

以上這一行

?
1
thread.setName(“自定義線程名稱”);

是設置線程名稱,可以通過Thread.currentThread().getName()拿到該名稱,便于在日志中進行排查問題。

小結一下

集群版本如果要使用@Scheduled的話,需要加分布式鎖來控制,或者直接用分布式定時任務Elasticjob或者xxl-job等。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/qq_30698633/article/details/78024127

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产麻豆精品入口在线观看 | 亚洲AV午夜福利精品香蕉麻豆 | 99久久精品国语对白 | 国产经典一区二区三区蜜芽 | 毛片网在线观看 | 日岳母小说| 午夜欧美精品久久久久久久久 | 国产婷婷综合丁香亚洲欧洲 | 黑人巨鞭大战白妞10级 | 91麻豆精品国产片在线观看 | 国产愉拍精品视频手机 | 日韩成a人片在线观看日本 日韩不卡一区二区 | 日韩精品一区二区三区中文字幕 | 奇米狠狠色 | 久久久久久久尹人综合网亚洲 | 久久综久久美利坚合众国 | 国产激情视频网站 | 二次元美女扒开内裤露尿口 | 国产免费不卡视频 | 成年性生交大片免费看 | 日本道在线播放 | 精品视频网站 | 精品在线视频一区 | 99av涩导航 | 美女禁区视频无遮挡免费看 | 99久视频| 亚洲精品www久久久久久久软件 | 日韩欧美亚洲国产高清在线 | 和肥岳在厨房激情 | 免费一级国产生活片 | 国内小情侣一二三区在线视频 | 欧美另类老女人 | 女教师波多野结衣高清在线 | 五月丁香啪啪. | www视频免费观看 | 国产视频中文字幕 | videojapan日本孕交孕 | 国产亚洲人成网站天堂岛 | 亚洲精品高清中文字幕完整版 | 亚洲国产香蕉视频欧美 | 亚洲 欧美 日本 国产 高清 |