spring boot中的定時(shí)任務(wù)

在spring boot中教沾,簡(jiǎn)單的任務(wù)調(diào)度工作可以由@Scheduled注解來完成沾瓦。

如果需要深入了解spring的調(diào)度心铃,最好的方式是先看下官方文檔准谚。

一、Spring的任務(wù)抽象接口

TaskExecutor接口

TaskExecutor是任務(wù)執(zhí)行接口去扣,類似于java.util.concurrent.Executor柱衔,該接口只有一個(gè)方法execute(Runnable task),用于執(zhí)行任務(wù)厅篓。

Spring提供了一組TaskExecutor的實(shí)現(xiàn)秀存,基本上能滿足所有的需求。它們的使用方式跟普通的Spring Bean一樣羽氮。

TaskScheduler接口

TaskScheduler接口是定時(shí)器的抽象或链,它的源代碼如下〉笛海可以看到澳盐,該接口包含了一組方法用于指定任務(wù)執(zhí)行的時(shí)間。

public interface TaskScheduler {

    ScheduledFuture schedule(Runnable task, Trigger trigger);

    ScheduledFuture schedule(Runnable task, Date startTime);

    ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);

    ScheduledFuture scheduleAtFixedRate(Runnable task, long period);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

    ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);

}

二令宿、實(shí)操

2.1叼耙、定時(shí)任務(wù)

具體步驟如下:

1. 在應(yīng)用入口增加@EnableScheduling

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String [] args) {
        SpringApplication.run(Application.class, args);
    }
}

如果應(yīng)用依賴了spring-boot-starter-actuator,即使沒有聲明@EnableScheduling粒没,調(diào)度任務(wù)也會(huì)被執(zhí)行筛婉。因?yàn)?code>spring-boot-starter-actuator本身也聲明了@EnableScheduling,見MetricExportAutoConfiguration癞松。

2. 增加任務(wù)調(diào)度服務(wù)

@Component // 或@Service
public class TaskService {

    @Scheduled(fixedRate = 1000) // 每隔1秒執(zhí)行一次
    public void timerRate() {
        // 在此處執(zhí)行調(diào)度任務(wù)爽撒。
    }
}

@Scheduled 注解主要使用在執(zhí)行調(diào)度任務(wù)的方法上入蛆。

注意!Springboot 默認(rèn)的執(zhí)行方式是串行執(zhí)行硕勿,無論有多少task(@Scheduled)哨毁,都是一個(gè)線程串行執(zhí)行。同一個(gè)task源武,如果前一個(gè)還沒跑完后面一個(gè)就不會(huì)觸發(fā)扼褪,不同的task也不能同時(shí)運(yùn)行,這是因?yàn)閟cheduler的默認(rèn)線程數(shù)為1的緣故粱栖。

在高可用的情況下话浇,如果微服務(wù)有多個(gè)實(shí)例,scheduler會(huì)在多個(gè)實(shí)例上同時(shí)運(yùn)行查排。

2.2凳枝、并行任務(wù)

在上面的基礎(chǔ)上,增加一個(gè)實(shí)現(xiàn)SchedulingConfigurer接口的類:

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

    private final int POOL_SIZE = 10;
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        // 線程前綴
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }

  /*  @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
 
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(POOL_SIZE); // 線程池初始化10個(gè)線程
    }*/
}

如果在調(diào)度方法里打印當(dāng)前線程名稱:

Current Thread : my-scheduled-task-pool-1
Current Thread : my-scheduled-task-pool-2
...

配置多個(gè)線程會(huì)導(dǎo)致同一個(gè)task前一個(gè)還沒跑完后面又被觸發(fā)的問題跋核。

附錄1岖瑰、@Scheduled中的參數(shù)

(1) cron:cron表達(dá)式,指定任務(wù)在特定時(shí)間執(zhí)行;
(2) fixedDelay:表示上一次任務(wù)執(zhí)行完成后多久再次執(zhí)行砂代,參數(shù)類型為long蹋订,單位ms;
(3) fixedDelayString:與fixedDelay含義一樣,只是參數(shù)類型變?yōu)镾tring;
(4) fixedRate:表示按一定的頻率執(zhí)行任務(wù)刻伊,參數(shù)類型為long露戒,單位ms;
(5) fixedRateString: 與fixedRate的含義一樣,只是將參數(shù)類型變?yōu)镾tring;
(6) initialDelay:表示延遲多久再第一次執(zhí)行任務(wù)捶箱,參數(shù)類型為long智什,單位ms;
(7) initialDelayString:與initialDelay的含義一樣,只是將參數(shù)類型變?yōu)镾tring;
(8) zone:時(shí)區(qū)丁屎,默認(rèn)為當(dāng)前時(shí)區(qū)荠锭,一般沒有用到。

例子:

  • @Scheduled(fixedRate=1000): 上一次開始執(zhí)行后1秒再次執(zhí)行晨川;
  • @Scheduled(fixedDelay=1000):上一次執(zhí)行完成后1秒再次執(zhí)行证九;
  • @Scheduled(initialDelay=1000, fixedDelay=3000):第一次延遲1秒執(zhí)行,然后在上一次執(zhí)行完成后3秒再次執(zhí)行共虑;
  • @Scheduled(cron="* * * * * ?"):按cron表達(dá)式執(zhí)行愧怜。

附錄2、CRON表達(dá)式

Cron格式

Quartz的官方文檔

一個(gè) Cron表達(dá)式是由6或7個(gè)字段(年字段是可選字段)的字符串組成妈拌,字段與字段之間用空格來隔開拥坛。
Cron表達(dá)式使用格式:

Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
時(shí) [年]

各個(gè)域的定義:

必輸 含義 允許值 允許特殊符號(hào)
Seconds 0-59 , - * /
Minutes 0-59 , - * /
Hours 時(shí) 0-23 , - * /
Day of Month 1-31 , - * ? / L W
Month 1-12或者 JAN-DEC , - * /
Day of Week 1-7 或者 SUN-SAT , - * ? / L #
[Year] [年] 空,1970-2099 , - * /

特殊符號(hào)代表的含義:

符號(hào) 含義
* 匹配該域的任意值;如*用在所在的域渴逻,表示每分鐘都會(huì)觸發(fā)事件疾党。
? 無特定值。只能用在DayofMonthDayofWeek兩個(gè)域惨奕。 由于DayofMonthDayofWeek這兩個(gè)元素是互斥的,必須要對(duì)其中一個(gè)設(shè)置?竭钝。例如想在每月的20日觸發(fā)調(diào)度梨撞,不管20日到底是星期幾,則只能使用如下寫法: 13 13 15 20 * ?, 其中最后一位只能用香罐?卧波,而不能使用*,如果使用*表示不管星期幾都會(huì)觸發(fā)庇茫。
- 匹配一個(gè)特定的范圍值港粱;如時(shí)所在的域的值是10-12,表示10旦签、11查坪、12點(diǎn)的時(shí)候會(huì)觸發(fā)事件.
, 匹配多個(gè)指定的值;如所在的域的值是2,4,6宁炫,表示在周一偿曙、周三、周五就會(huì)觸發(fā)事件羔巢。(1表示周日望忆,2表示周一,3表示周二竿秆,以此類推启摄,7表示周六)。
/ 指定數(shù)值的增量幽钢。左邊是開始觸發(fā)時(shí)間歉备,右邊是每隔固定時(shí)間觸發(fā)一次事件,如秒所在的域的值是5/15搅吁,表示從第5秒開始威创,每15秒觸發(fā),即在第5秒谎懦、20秒肚豺、35秒、50秒的時(shí)候都觸發(fā)一次事件界拦,等價(jià)于“5,20,35,50”吸申。
L last,最后的意思,如果是用在這個(gè)域截碴,表示月的最后一天梳侨,如果是用在周所在的域,如6L日丹,表示某個(gè)月最后一個(gè)周五走哺。
W weekday,工作日的意思哲虾。如所在的域的值是15W丙躏,表示本月15日最近的工作日,如果15日是周六束凑,觸發(fā)器將觸發(fā)上14日周五晒旅。如果15日是周日,觸發(fā)器將觸發(fā)16日周一汪诉。如果15日不是周六或周日废恋,而是周一至周五的某一個(gè),那么它就在15日當(dāng)天觸發(fā)事件。
# 用來指定每個(gè)月的第幾個(gè)星期幾,如6#3表示某個(gè)月的第三個(gè)星期五运挫。

CRON表達(dá)式官方例子

表達(dá)式 含義
"0 0 12 * * ?" 每天12:00觸發(fā)事件
"0 15 10 ? * *" 每天10:15觸發(fā)事件
"0 15 10 * * ?" 每天10:15觸發(fā)事件
"0 15 10 * * ? *" 每天10:15觸發(fā)事件
"0 15 10 * * ? 2005" 2005年的每天10:15觸發(fā)事件
"0 * 14 * * ?" 每天14點(diǎn)開始觸發(fā),每分鐘觸發(fā)一次蚓哩,14:59分結(jié)束
"0 0/5 14 * * ?" 每天14點(diǎn)開始觸發(fā)到14:59分結(jié)束的每5分鐘觸發(fā)一次事件
"0 0/5 14,18 * * ?" 每天14點(diǎn)開始到14:59期間和18點(diǎn)到18:59期間的每5分鐘觸發(fā)一次事件
"0 0-5 14 * * ?" 每天14點(diǎn)到14:05期間的每1分鐘觸發(fā)一次事件
"0 10,44 14 ? 3 WED" 每年3月的星期三的14:10和14:44觸發(fā)一次事件
"0 15 10 ? * MON-FRI" 周一至周五的10:15觸發(fā)一次事件
"0 15 10 15 * ?" 每月15日10:15觸發(fā)一次事件
"0 15 10 L * ?" 每月最后一日的10:15觸發(fā)一次事件
"0 15 10 ? * 6L" 每月的最后一個(gè)星期五10:15觸發(fā)一次事件
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一個(gè)星期五10:15觸發(fā)一次事件
"0 15 10 ? * 6#3" 每月的第三個(gè)星期五10:15觸發(fā)一次事件
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市上渴,隨后出現(xiàn)的幾起案子岸梨,更是在濱河造成了極大的恐慌,老刑警劉巖稠氮,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曹阔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡隔披,警方通過查閱死者的電腦和手機(jī)赃份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奢米,“玉大人抓韩,你說我怎么就攤上這事△蕹ぃ” “怎么了谒拴?”我有些...
    開封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)涉波。 經(jīng)常有香客問我英上,道長(zhǎng)炭序,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任苍日,我火速辦了婚禮惭聂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘相恃。我一直安慰自己辜纲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開白布豆茫。 她就那樣靜靜地躺著侨歉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揩魂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天炮温,我揣著相機(jī)與錄音火脉,去河邊找鬼。 笑死柒啤,一個(gè)胖子當(dāng)著我的面吹牛倦挂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播担巩,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼方援,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了涛癌?” 一聲冷哼從身側(cè)響起犯戏,我...
    開封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拳话,沒想到半個(gè)月后先匪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弃衍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年呀非,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镜盯。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岸裙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出速缆,到底是詐尸還是另有隱情降允,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布激涤,位于F島的核電站拟糕,受9級(jí)特大地震影響判呕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜送滞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一侠草、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧犁嗅,春花似錦边涕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至宠蚂,卻和暖如春式撼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背求厕。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工著隆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呀癣。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓美浦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親项栏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浦辨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355