SpringBoot通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及單線程運(yùn)行問(wèn)題解決
一、開(kāi)啟定時(shí)任務(wù)方法
Scheduled定時(shí)任務(wù)是Spring boot自身提供的功能,所以不需要引入Maven依賴(lài)包
在項(xiàng)目入口main方法上加注解
@EnableScheduling //開(kāi)啟定時(shí)任務(wù)
二、不同定時(shí)方式的解析
1.fixedDelay和fixedRate,單位是毫秒,它們的區(qū)別就是:
fixedRate就是每隔多長(zhǎng)時(shí)間執(zhí)行一次。(開(kāi)始------->X時(shí)間------>再開(kāi)始)。如果間隔時(shí)間小于任務(wù)執(zhí)行時(shí)間,上一次任務(wù)執(zhí)行完成下一次任務(wù)就立即執(zhí)行。如果間隔時(shí)間大于任務(wù)執(zhí)行時(shí)間,就按照每隔X時(shí)間運(yùn)行一次。
而fixedDelay是當(dāng)任務(wù)執(zhí)行完畢后一段時(shí)間再次執(zhí)行。(開(kāi)始—>結(jié)束(隔一分鐘)開(kāi)始----->結(jié)束)。上一次執(zhí)行任務(wù)未完成,下一次任務(wù)不會(huì)開(kāi)始。
2.cron表達(dá)式:靈活
舉例說(shuō)明
| 表達(dá)式 | 說(shuō)明 |
|---|---|
| 0 0 3 * * ? | 每天3點(diǎn)執(zhí)行 |
| 0 5 3 * * ? | 每天3點(diǎn)5分執(zhí)行 |
| 0 5 3 ? * * | 每天3點(diǎn)5分執(zhí)行,與上面作用相同 |
| 0 5/10 3 * * ? | 每天3點(diǎn)的 5分,15分,25分,35分,45分,55分這幾個(gè)時(shí)間點(diǎn)執(zhí)行 |
| 0 10 3 ? * 1 | 每周星期天,3點(diǎn)10分 執(zhí)行,注:1表示星期天 |
| 0 10 3 ? * 1#3 | 每個(gè)月的第三個(gè)星期,星期天 執(zhí)行,#號(hào)只能出現(xiàn)在星期的位置 |
- 第一位,表示秒,取值0-59
- 第二位,表示分,取值0-59
- 第三位,表示小時(shí),取值0-23
- 第四位,日期天/日,取值1-31
- 第五位,日期月份,取值1-12
- 第六位,星期,取值1-7,星期一,星期二…,注:不是第1周,第二周的意思,另外:1表示星期天,2表示星期一。
- 第七位,年份,可以留空,取值1970-2099
cron中,還有一些特殊的符號(hào),含義如下:
- ()星號(hào):可以理解為每的意思,每秒,每分,每天,每月,每年…
- (?)問(wèn)號(hào):?jiǎn)柼?hào)只能出現(xiàn)在日期和星期這兩個(gè)位置。
- (-)減號(hào):表達(dá)一個(gè)范圍,如在小時(shí)字段中使用“10-12”,則表示從10到12點(diǎn),即10,11,12
- (,)逗號(hào):表達(dá)一個(gè)列表值,如在星期字段中使用“1,2,4”,則表示星期一,星期二,星期四
- (/)斜杠:如:x/y,x是開(kāi)始值,y是步長(zhǎng),比如在第一位(秒) 0/15就是,從0秒開(kāi)始,每15秒,最后就是0,15,30,45,60 另:/y,等同于0/y
cron表達(dá)式在線:http://tools.jb51.net/code/Quartz_Cron_create
三、實(shí)現(xiàn)定時(shí)任務(wù)
@Component
public class ScheduledJobs {
//表示方法執(zhí)行完成后5秒再開(kāi)始執(zhí)行
@Scheduled(fixedDelay=5000)
public void fixedDelayJob() throws InterruptedException{
System.out.println("fixedDelay 開(kāi)始:" + new Date());
Thread.sleep(10 * 1000);
System.out.println("fixedDelay 結(jié)束:" + new Date());
}
//表示每隔3秒
@Scheduled(fixedRate=3000)
public void fixedRateJob()throws InterruptedException{
System.out.println("===========fixedRate 開(kāi)始:" + new Date());
Thread.sleep(5 * 1000);
System.out.println("===========fixedRate 結(jié)束:" + new Date());
}
//表示每隔10秒執(zhí)行一次
@Scheduled(cron="0/10 * * * * ? ")
public void cronJob(){
System.out.println("=========================== ...>>cron...." + new Date());
}
}
運(yùn)行結(jié)果如下:從運(yùn)行結(jié)果上看,并未按照預(yù)期的時(shí)間規(guī)律運(yùn)行。仔細(xì)看線程打印,竟然所有的定時(shí)任務(wù)使用的都是一個(gè)線程,所以彼此互相影響。
===========fixedRate 結(jié)束:Tue Jul 09 19:53:04 CST 2019pool-1-thread-1
fixedDelay 開(kāi)始:Tue Jul 09 19:53:04 CST 2019pool-1-thread-1
fixedDelay 結(jié)束:Tue Jul 09 19:53:14 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:14 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:16 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:16 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:18 CST 2019pool-1-thread-1
=========================== ...>>cron....Tue Jul 09 19:53:18 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:18 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:20 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:20 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:22 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:22 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:24 CST 2019pool-1-thread-1
fixedDelay 開(kāi)始:Tue Jul 09 19:53:24 CST 2019pool-1-thread-1
fixedDelay 結(jié)束:Tue Jul 09 19:53:34 CST 2019pool-1-thread-1
=========================== ...>>cron....Tue Jul 09 19:53:34 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:34 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:36 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:36 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:38 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:38 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:40 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:40 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:42 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:42 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:44 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:44 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:46 CST 2019pool-1-thread-1
===========fixedRate 開(kāi)始:Tue Jul 09 19:53:46 CST 2019pool-1-thread-1
===========fixedRate 結(jié)束:Tue Jul 09 19:53:48 CST 2019pool-1-thread-1
fixedDelay 開(kāi)始:Tue Jul 09 19:53:48 CST 2019pool-1-thread-1
fixedDelay 結(jié)束:Tue Jul 09 19:53:58 CST 2019pool-1-thread-1
=========================== ...>>cron....Tue Jul 09 19:53:58 CST 2019pool-1-thread-1
四、解決定時(shí)任務(wù)單線程運(yùn)行的問(wèn)題
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(scheduledTaskExecutor());
}
@Bean
public Executor scheduledTaskExecutor() {
return Executors.newScheduledThreadPool(3); //指定線程池大小
}
}
再次運(yùn)行上面的程序,運(yùn)行時(shí)間規(guī)律就符合期望了。
總結(jié)
到此這篇關(guān)于SpringBoot通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及單線程運(yùn)行問(wèn)題解決的文章就介紹到這了,更多相關(guān)SpringBoot @Scheduled實(shí)現(xiàn)定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中定時(shí)任務(wù)@Scheduled的多線程使用詳解
- SpringBoot?ScheduledTaskRegistrar解決動(dòng)態(tài)定時(shí)任務(wù)思路詳解
- SpringBoot定時(shí)任務(wù)動(dòng)態(tài)擴(kuò)展ScheduledTaskRegistrar詳解
- SpringBoot中定時(shí)任務(wù)@Scheduled注解的使用解讀
- 解決SpringBoot中的Scheduled單線程執(zhí)行問(wèn)題
- SpringBoot中使用@scheduled定時(shí)執(zhí)行任務(wù)的坑
- springboot使用定時(shí)器@Scheduled不管用的解決
- 帶你3分鐘帶你搞定Spring Boot中Schedule
相關(guān)文章
用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM
這篇文章主要介紹了用Spring Native將SpringBoot程序轉(zhuǎn)換為GraalVM的方法,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下2021-04-04
SpringBoot實(shí)現(xiàn)圖形驗(yàn)證碼的操作方法
隨著安全性的要求越來(lái)越高,目前許多項(xiàng)目中都使用了驗(yàn)證碼,驗(yàn)證碼也有各種類(lèi)型,如 圖形驗(yàn)證碼、短信驗(yàn)證碼、郵件驗(yàn)證碼、人臉識(shí)別等,本文給大家介紹SpringBoot實(shí)現(xiàn)圖形驗(yàn)證碼的方法,感興趣的朋友跟隨小編一起看看吧2024-07-07
Java多態(tài)和實(shí)現(xiàn)接口的類(lèi)的對(duì)象賦值給接口引用的方法(推薦)
下面小編就為大家?guī)?lái)一篇Java多態(tài)和實(shí)現(xiàn)接口的類(lèi)的對(duì)象賦值給接口引用的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
java并發(fā)編程專(zhuān)題(八)----(JUC)實(shí)例講解CountDownLatch
這篇文章主要介紹了java CountDownLatch的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
Java業(yè)務(wù)校驗(yàn)工具實(shí)現(xiàn)方法
這篇文章主要介紹了Java業(yè)務(wù)校驗(yàn)工具實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Java使用easyExcel實(shí)現(xiàn)導(dǎo)入功能
這篇文章介紹了Java使用easyExcel實(shí)現(xiàn)導(dǎo)入功能的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
Spring中@ExceptionHandler注解的使用方式
這篇文章主要介紹了Spring中@ExceptionHandler注解的使用方式,@ExceptionHandler注解我們一般是用來(lái)自定義異常的,可以認(rèn)為它是一個(gè)異常攔截器(處理器),需要的朋友可以參考下2024-01-01
java基于odbc連接oracle的實(shí)現(xiàn)方法
這篇文章主要介紹了java基于odbc連接oracle的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了連接操作的具體步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-09-09

