關(guān)于@Scheduled參數(shù)及cron表達(dá)式解釋
@Scheduled參數(shù)及cron表達(dá)式解釋
@Scheduled支持以下8個(gè)參數(shù)
- 1.
cron
:表達(dá)式,指定任務(wù)在特定時(shí)間執(zhí)行; - 2.
fixedDelay
:表示上一次任務(wù)執(zhí)行完成后多久再次執(zhí)行,參數(shù)類型為long,單位ms; - 3.
fixedDelayString
:與fixedDelay含義一樣,只是參數(shù)類型變?yōu)镾tring; - 4.
fixedRate
:表示按一定的頻率執(zhí)行任務(wù),即每次開始執(zhí)行的時(shí)間間隔一致,參數(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ū)。
cron表達(dá)式是一個(gè)字符串,以空格分開共6個(gè)域
- [秒] [分] [時(shí)] [日] [月] [周]
- spring自帶的定時(shí)任務(wù)cron表達(dá)式不支持年
如圖:
上圖類中有如下源代碼:
private void parse(String expression) throws IllegalArgumentException { String[] fields = StringUtils.tokenizeToStringArray(expression, " "); if (!areValidCronFields(fields)) { throw new IllegalArgumentException(String.format( "Cron expression must consist of 6 fields (found %d in \"%s\")", fields.length, expression)); } doParse(fields); } private static boolean areValidCronFields(String[] fields) { return (fields != null && fields.length == 6); }
代碼中expression參數(shù)即cron表達(dá)式,所以在spring自帶的定時(shí)任務(wù)中正確的cron表達(dá)式只能是6個(gè)域,否則會(huì)拋出IllegalArgumentException提示:Cron expression must consist of 6 fields(cron表達(dá)式必須由6個(gè)域組成)。
域 | 必填 | 允許值 | 允許的通配符 |
---|---|---|---|
秒(seconds) | 是 | 0-59整數(shù) | , - * / |
分(minutes) | 是 | 0-59整數(shù) | , - * / |
時(shí)(hours) | 是 | 0-23整數(shù) | , - * / |
日(daysOfMonth) | 是 | 1-31整數(shù)(需要考慮月的天數(shù)) | , - * ? / L W |
月(months) | 是 | 1-12整數(shù) 或 JAN-DEC | , - * / |
周 (daysOfWeek) | 是 | 1-7整數(shù) 或 SUN-SAT | , - * ? / L # |
通配符說(shuō)明
*
:表示匹配該域的任意值。在minutes域使用 * 表示每分鐘。在months里表示每個(gè)月。在daysOfWeek域表示一周的每一天。?
:只能用在daysofMonth和daysofWeek兩個(gè)域,表示不指定值,當(dāng)兩個(gè)子表達(dá)式其中之一被指定了值以后,為了避免沖突,需要將另一個(gè)子表達(dá)式的值設(shè)為 ?。因?yàn)閐aysofMonth和daysofWeek會(huì)相互影響。例如想在每月的2號(hào)觸發(fā)調(diào)度,不管2號(hào)是周幾,則只能使用如下寫法:0 0 0 2 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管周幾都會(huì)觸發(fā)。-
:表示范圍。例如在minutes域使用5-20,表示從5分到20分鐘每分鐘觸發(fā)一次/
:表示起始時(shí)間開始觸發(fā),然后每隔固定時(shí)間觸發(fā)一次。例如在minutes域使用5/20,則意味著從當(dāng)前小時(shí)的第5分鐘開每20分鐘觸發(fā)一次。,
:表示列出枚舉值。例如:在minutes域使用5,20,則意味著在5分和20分時(shí)各觸發(fā)一次。L
:表示最后,是單詞“l(fā)ast”的縮寫,只能出現(xiàn)在daysofWeek和dayofMonth域。在daysofWeek域使用5L意思是在指定月的最后的一個(gè)星期四觸發(fā)。在dayofMonth域使用5L或者FRIL意思是在指定月的倒數(shù)第5天觸發(fā)。在使用L參數(shù)時(shí),不要指定列表或范圍。W
:表示有效工作日(周一到周五),只能出現(xiàn)在daysofMonth域,系統(tǒng)將在離指定日期的最近的有效工作日觸發(fā)事件。例如:在daysofMonth使用5W,如果5號(hào)是周六,則將在最近的工作日周五,即4號(hào)觸發(fā)。如果5號(hào)是周日,則在6日(周一)觸發(fā)。如果5日在星期一到星期五中的一天,則就在5日觸發(fā)。另外,W的最近尋找不會(huì)跨過(guò)月份 。LW
:這兩個(gè)字符可以連用,表示指定月的最后一個(gè)工作日。#
:用于確定每個(gè)月第幾個(gè)周幾,只能出現(xiàn)在daysofMonth域。例如在4#2,表示某月的第二個(gè)周三。
常用表達(dá)式示例
0/2 * * * * ?
表示每2秒 執(zhí)行任務(wù)0 0/2 * * * ?
表示每2分鐘 執(zhí)行任務(wù)0 0 2 1 * ?
表示在每月的1日的凌晨2點(diǎn)調(diào)整任務(wù)0 15 10 ? * MON-FRI
表示周一到周五每天上午10:15執(zhí)行作業(yè)0 0 10,14,16 * * ?
每天上午10點(diǎn),下午2點(diǎn),4點(diǎn)0 0/30 9-17 * * ?
朝九晚五工作時(shí)間內(nèi)每半小時(shí)0 0 12 ? * WED
表示每個(gè)星期三中午12點(diǎn)0 0 12 * * ?
每天中午12點(diǎn)觸發(fā)0 15 10 ? * *
每天上午10:15觸發(fā)0 15 10 * * ?
每天上午10:15觸發(fā)0 15 10 * * ?
每天上午10:15觸發(fā)0 * 14 * * ?
在每天下午2點(diǎn)到下午2:59期間的每1分鐘觸發(fā)0 0/5 14 * * ?
在每天下午2點(diǎn)到下午2:55期間的每5分鐘觸發(fā)0 0/5 14,18 * * ?
在每天下午2點(diǎn)到2:55期間和下午6點(diǎn)到6:55期間的每5分鐘觸發(fā)0 0-5 14 * * ?
在每天下午2點(diǎn)到下午2:05期間的每1分鐘觸發(fā)0 10,44 14 ? 3 WED
每年三月的星期三的下午2:10和2:44觸發(fā)0 15 10 ? * MON-WED,SAT
周一至周三和周六的上午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 ? * 6#3
每月的第三個(gè)星期五上午10:15觸發(fā)
@Scheduled 定時(shí)任務(wù)總結(jié)
@Scheduled
- 作用:spring定時(shí)器(定時(shí)執(zhí)行一次或定時(shí)輪詢執(zhí)行一段代碼)
- 使用場(chǎng)景:注解在方法上
- 參數(shù)說(shuō)明:常用參數(shù)
@Scheduled 參數(shù)說(shuō)明
String cron
:cron表達(dá)式定義了方法執(zhí)行的時(shí)間規(guī)則(網(wǎng)上對(duì)這個(gè)的說(shuō)明很多就不墨跡了)
生成器工具地址-http://cron.qqe2.com/
- Long fixedDelay:定時(shí)任務(wù)每隔多久執(zhí)行一次,單位是毫秒,上一次任務(wù)結(jié)束后開始計(jì)算下次執(zhí)行的時(shí)間。
例子:@Scheduled(fixedDelay = 1000 * 10) //10秒發(fā)送一次
······················scheduled1開始執(zhí)行·······················2018-07-27 14:00:00
······················scheduled1結(jié)束執(zhí)行·······················2018-07-27 14:00:05
······················scheduled2開始執(zhí)行·······················2018-07-27 14:00:15
······················scheduled2結(jié)束執(zhí)行·······················2018-07-27 14:00:20
······················scheduled3開始執(zhí)行·······················2018-07-27 14:00:30
······················scheduled3結(jié)束執(zhí)行·······················2018-07-27 14:00:35
Long fixedRate
:與fixedDelay一樣表示定時(shí)任務(wù)的執(zhí)行時(shí)間間隔,不同的是fixedRate的不會(huì)受到上一次任務(wù)結(jié)束時(shí)間的影響
例子:@Scheduled(fixedRate = 1000 * 10) //10秒發(fā)送一次
······················scheduled1開始執(zhí)行·······················2018-07-27 14:00:00
······················scheduled1結(jié)束執(zhí)行·······················2018-07-27 14:00:05
······················scheduled2開始執(zhí)行·······················2018-07-27 14:00:10
······················scheduled2結(jié)束執(zhí)行·······················2018-07-27 14:00:15
······················scheduled3開始執(zhí)行·······················2018-07-27 14:00:20
······················scheduled3結(jié)束執(zhí)行·······················2018-07-27 14:00:25
Long initialDelay
:項(xiàng)目啟動(dòng)后不馬上執(zhí)行定時(shí)器,根據(jù)initialDelay的值延時(shí)執(zhí)行。
注意事項(xiàng)
1.定時(shí)器的參數(shù)有兩種寫法是用cron表達(dá)式,或者使用fixedDelay、fixedRate等參數(shù)直接配置
需要注意的是 使用cron表達(dá)式的方法,在項(xiàng)目首次啟動(dòng)后不會(huì)直接運(yùn)行,而是等到執(zhí)行周期才會(huì)執(zhí)行
而使用第二種方式的定時(shí)器方法,在項(xiàng)目啟動(dòng)成功后會(huì)馬上開始執(zhí)行一次,再按照時(shí)間周期執(zhí)行。
測(cè)試說(shuō)明:
使用第一種配置方式,項(xiàng)目啟動(dòng)后方法不會(huì)執(zhí)行,而是等到執(zhí)行周期到了才會(huì)執(zhí)行方法
使用第二種參數(shù)方式的方法,項(xiàng)目啟動(dòng)成功后馬上執(zhí)行了一次
2.定時(shí)器默認(rèn)為單線程,所以如果項(xiàng)目中使用多個(gè)定時(shí)器要配置線程池
注意這里的@EnableScheduling,使用它來(lái)開啟定時(shí)器注解
@Configuration @EnableScheduling public class SchedulingConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(5 ,new ThreadFactory() { private final AtomicLong counter = new AtomicLong(); @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("test-scheduler-" + counter.incrementAndGet()); return thread; } }); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)戰(zhàn)寵物醫(yī)院預(yù)約掛號(hào)系統(tǒng)的實(shí)現(xiàn)流程
只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+JSP+Spring+SpringBoot+MyBatis+html+layui+maven+Mysql實(shí)現(xiàn)一個(gè)寵物醫(yī)院預(yù)約掛號(hào)系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2022-01-01Java實(shí)現(xiàn)的簡(jiǎn)單字符串反轉(zhuǎn)操作示例
這篇文章主要介紹了Java實(shí)現(xiàn)的簡(jiǎn)單字符串反轉(zhuǎn)操作,結(jié)合實(shí)例形式分別描述了java遍歷逆序輸出以及使用StringBuffer類的reverse()方法兩種字符串反轉(zhuǎn)操作技巧,需要的朋友可以參考下2018-08-08詳解Kotlin:forEach也能break和continue
這篇文章主要介紹了詳解Kotlin:forEach也能break和continue的相關(guān)資料,需要的朋友可以參考下2017-06-06Java Collection和Collections的區(qū)別
本文主要介紹了Java Collection和Collections的區(qū)別,Collection?是表示集合的接口,而?Collections?是對(duì)集合進(jìn)行操作的工具類,下面就來(lái)介紹一下具體用法,感興趣的可以了解一下2023-12-12SpringMVC深入講解文件的上傳下載實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了springMVC實(shí)現(xiàn)文件上傳和下載的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06java調(diào)用chatgpt接口來(lái)實(shí)現(xiàn)專屬于自己的人工智能助手
這篇文章主要介紹了用java來(lái)調(diào)用chatget的接口,實(shí)現(xiàn)自己的聊天機(jī)器人,對(duì)人工智能感興趣的小伙伴可以參考閱讀2023-03-03Seata分布式事務(wù)出現(xiàn)ABA問(wèn)題解決
這篇文章主要為大家介紹了Seata分布式事務(wù)出現(xiàn)ABA問(wèn)題解決方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11idea?maven?經(jīng)常主目錄自動(dòng)變回默認(rèn)的解決方法
很多朋友反映idea?maven?經(jīng)常主目錄自動(dòng)變回默認(rèn),遇到這樣的問(wèn)題真的很頭疼,該如何解決呢?下面小編給大家介紹下idea?maven目錄變回默認(rèn)的解決方法,需要的朋友可以參考下2022-08-08