關於@Scheduled參數及cron表達式解釋
@Scheduled參數及cron表達式解釋
@Scheduled支持以下8個參數
- 1.
cron
:表達式,指定任務在特定時間執行; - 2.
fixedDelay
:表示上一次任務執行完成後多久再次執行,參數類型為long,單位ms; - 3.
fixedDelayString
:與fixedDelay含義一樣,隻是參數類型變為String; - 4.
fixedRate
:表示按一定的頻率執行任務,即每次開始執行的時間間隔一致,參數類型為long,單位ms; - 5.
fixedRateString
:與fixedRate的含義一樣,隻是將參數類型變為String; - 6.
initialDelay
:表示延遲多久再第一次執行任務,參數類型為long,單位ms; - 7.
initialDelayString
:與initialDelay的含義一樣,隻是將參數類型變為String; - 8.
zone
:時區,默認為當前時區。
cron表達式是一個字符串,以空格分開共6個域
- [秒] [分] [時] [日] [月] [周]
- spring自帶的定時任務cron表達式不支持年
如圖:
上圖類中有如下源代碼:
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參數即cron表達式,所以在spring自帶的定時任務中正確的cron表達式隻能是6個域,否則會拋出IllegalArgumentException提示:Cron expression must consist of 6 fields(cron表達式必須由6個域組成)。
域 | 必填 | 允許值 | 允許的通配符 |
---|---|---|---|
秒(seconds) | 是 | 0-59整數 | , – * / |
分(minutes) | 是 | 0-59整數 | , – * / |
時(hours) | 是 | 0-23整數 | , – * / |
日(daysOfMonth) | 是 | 1-31整數(需要考慮月的天數) | , – * ? / L W |
月(months) | 是 | 1-12整數 或 JAN-DEC | , – * / |
周 (daysOfWeek) | 是 | 1-7整數 或 SUN-SAT | , – * ? / L # |
通配符說明
*
:表示匹配該域的任意值。在minutes域使用 * 表示每分鐘。在months裡表示每個月。在daysOfWeek域表示一周的每一天。?
:隻能用在daysofMonth和daysofWeek兩個域,表示不指定值,當兩個子表達式其中之一被指定瞭值以後,為瞭避免沖突,需要將另一個子表達式的值設為 ?。因為daysofMonth和daysofWeek會相互影響。例如想在每月的2號觸發調度,不管2號是周幾,則隻能使用如下寫法:0 0 0 2 * ?, 其中最後一位隻能用?,而不能使用*,如果使用*表示不管周幾都會觸發。-
:表示范圍。例如在minutes域使用5-20,表示從5分到20分鐘每分鐘觸發一次/
:表示起始時間開始觸發,然後每隔固定時間觸發一次。例如在minutes域使用5/20,則意味著從當前小時的第5分鐘開每20分鐘觸發一次。,
:表示列出枚舉值。例如:在minutes域使用5,20,則意味著在5分和20分時各觸發一次。L
:表示最後,是單詞“last”的縮寫,隻能出現在daysofWeek和dayofMonth域。在daysofWeek域使用5L意思是在指定月的最後的一個星期四觸發。在dayofMonth域使用5L或者FRIL意思是在指定月的倒數第5天觸發。在使用L參數時,不要指定列表或范圍。W
:表示有效工作日(周一到周五),隻能出現在daysofMonth域,系統將在離指定日期的最近的有效工作日觸發事件。例如:在daysofMonth使用5W,如果5號是周六,則將在最近的工作日周五,即4號觸發。如果5號是周日,則在6日(周一)觸發。如果5日在星期一到星期五中的一天,則就在5日觸發。另外,W的最近尋找不會跨過月份 。LW
:這兩個字符可以連用,表示指定月的最後一個工作日。#
:用於確定每個月第幾個周幾,隻能出現在daysofMonth域。例如在4#2,表示某月的第二個周三。
常用表達式示例
0/2 * * * * ?
表示每2秒 執行任務0 0/2 * * * ?
表示每2分鐘 執行任務0 0 2 1 * ?
表示在每月的1日的凌晨2點調整任務0 15 10 ? * MON-FRI
表示周一到周五每天上午10:15執行作業0 0 10,14,16 * * ?
每天上午10點,下午2點,4點0 0/30 9-17 * * ?
朝九晚五工作時間內每半小時0 0 12 ? * WED
表示每個星期三中午12點0 0 12 * * ?
每天中午12點觸發0 15 10 ? * *
每天上午10:15觸發0 15 10 * * ?
每天上午10:15觸發0 15 10 * * ?
每天上午10:15觸發0 * 14 * * ?
在每天下午2點到下午2:59期間的每1分鐘觸發0 0/5 14 * * ?
在每天下午2點到下午2:55期間的每5分鐘觸發0 0/5 14,18 * * ?
在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發0 0-5 14 * * ?
在每天下午2點到下午2:05期間的每1分鐘觸發0 10,44 14 ? 3 WED
每年三月的星期三的下午2:10和2:44觸發0 15 10 ? * MON-WED,SAT
周一至周三和周六的上午10:15觸發0 15 10 15 * ?
每月15日上午10:15觸發0 15 10 L * ?
每月最後一日的上午10:15觸發0 15 10 ? * 6L
每月的最後一個星期五上午10:15觸發0 15 10 ? * 6#3
每月的第三個星期五上午10:15觸發
@Scheduled 定時任務總結
@Scheduled
- 作用:spring定時器(定時執行一次或定時輪詢執行一段代碼)
- 使用場景:註解在方法上
- 參數說明:常用參數
@Scheduled 參數說明
String cron
:cron表達式定義瞭方法執行的時間規則(網上對這個的說明很多就不墨跡瞭)
生成器工具地址-http://cron.qqe2.com/
- Long fixedDelay:定時任務每隔多久執行一次,單位是毫秒,上一次任務結束後開始計算下次執行的時間。
例子:@Scheduled(fixedDelay = 1000 * 10) //10秒發送一次
······················scheduled1開始執行·······················2018-07-27 14:00:00
······················scheduled1結束執行·······················2018-07-27 14:00:05
······················scheduled2開始執行·······················2018-07-27 14:00:15
······················scheduled2結束執行·······················2018-07-27 14:00:20
······················scheduled3開始執行·······················2018-07-27 14:00:30
······················scheduled3結束執行·······················2018-07-27 14:00:35
Long fixedRate
:與fixedDelay一樣表示定時任務的執行時間間隔,不同的是fixedRate的不會受到上一次任務結束時間的影響
例子:@Scheduled(fixedRate = 1000 * 10) //10秒發送一次
······················scheduled1開始執行·······················2018-07-27 14:00:00
······················scheduled1結束執行·······················2018-07-27 14:00:05
······················scheduled2開始執行·······················2018-07-27 14:00:10
······················scheduled2結束執行·······················2018-07-27 14:00:15
······················scheduled3開始執行·······················2018-07-27 14:00:20
······················scheduled3結束執行·······················2018-07-27 14:00:25
Long initialDelay
:項目啟動後不馬上執行定時器,根據initialDelay的值延時執行。
註意事項
1.定時器的參數有兩種寫法是用cron表達式,或者使用fixedDelay、fixedRate等參數直接配置
需要註意的是 使用cron表達式的方法,在項目首次啟動後不會直接運行,而是等到執行周期才會執行
而使用第二種方式的定時器方法,在項目啟動成功後會馬上開始執行一次,再按照時間周期執行。
測試說明:
使用第一種配置方式,項目啟動後方法不會執行,而是等到執行周期到瞭才會執行方法
使用第二種參數方式的方法,項目啟動成功後馬上執行瞭一次
2.定時器默認為單線程,所以如果項目中使用多個定時器要配置線程池
註意這裡的@EnableScheduling,使用它來開啟定時器註解
@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; } }); } }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Spring Boot 2.x基礎教程之使用@Scheduled實現定時任務的方法
- springboot通過註解、接口創建定時任務詳解
- Java Spring分別實現定時任務方法
- Java中定時任務的6種實現方式
- SpringBoot中定時任務@Scheduled的多線程使用詳解