可参考文档 https://pdai.tech/md/develop/cron/dev-cron-x-usage.html
CRON
CRON 表达式
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
Seconds Minutes Hours DayofMonth Month DayofWeek Year
Seconds Minutes Hours DayofMonth Month DayofWeek
CRON 表达式的结构
Cron表达式是一个具有时间含义的字符串,字符串以5个空格隔开,分为6个域,格式为X X X X X X。其中X是一个域的占位符。单个域有多个取值时,使用半角逗号,隔开取值。每个域可以是确定的取值,也可以是具有逻辑意义的特殊字符。
域取值
| 域 | 是否必须 | 取值范围 | 特殊字符 |
|---|---|---|---|
| 秒 Seconds | 是 | [0, 59] |
*,-/ |
| 分钟 Minutes | 是 | [0, 59] |
*,-/ |
| 小时 Hours | 是 | [0, 23] |
*,-/ |
| 日期 DayofMonth | 是 | [1, 31] |
*,-/? L W |
| 月份 Month | 是 | [1, 12] 或 [JAN, DEC] |
*,-/ |
| 星期 DayofWeek | 是 | [1, 7] 或 [MON, SUN]。 若使用 [1, 7] 表达式,1 代表星期一,7代表星期日 |
*,-/? L # |
| 年 Year | 否 | 1970+ | -*/ |
特殊字符
Seconds Minutes Hours DayofMonth Month DayofWeek
| 特殊字符 | 含义 | 示例 |
|---|---|---|
* |
匹配任意值。 | 在字段月中,*表示每个月。 |
, |
列出枚举值。 | 在字段分钟中,5,20表示分别在5分钟和20分钟触发一次。 |
- |
指定范围。 | 在字段分钟中,5-20表示从5分钟到20分钟之间每隔一分钟触发一次。 |
/ |
指定数值的增量。 | 在字段分钟中,0/15表示从第0分钟开始,每15分钟。在字段分钟中3/20表示从第3分钟开始,每20分钟。 |
? |
不指定值,仅用于日期和星期。 | 当字段日期或星期其中之一被指定了值以后,即 DayofMonth 或 DayOfWeek,为了避免冲突,需要将另一个字段的值设为?。 |
L |
单词Last的首字母,表示最后一天,仅字段日期和星期支持该字符。重要 指定L字符时,避免指定列表或范围,否则会导致逻辑问题。 |
在字段日期中,L表示某个月的最后一天。在字段星期中,L表示一个星期的最后一天,也就是星期日(SUN)。如果在L前有具体的内容,例如,在字段星期中的6L表示这个月的最后一个星期六。 |
W |
除周末以外的有效工作日,在离指定日期的最近的有效工作日触发事件。W字符寻找最近有效工作日时不会跨过当前月份,连用字符LW时表示为指定月份的最后一个工作日。 |
在字段日期中5W,如果5日是星期六,则将在最近的工作日星期五,即4日触发。如果5日是星期天,则将在最近的工作日星期一,即6日触发;如果5日在星期一到星期五中的一天,则就在5日触发。 |
# |
确定每个月的第几个星期几。重要 仅字段星期支持该字符。 |
在字段星期中,4#2表示某月的第二个星期四。 |
L,避免且不能指定列表或范围,否则无效。比如 0 0 0 1-10,L * ? 不能即是每月的 1-10 号又是每月的最后一天,会出现歧义。也就是说,他不能和 , 或者 - 连用,只能单独使用。
如果你想表达每月的 1-10 号加上每月最后一天,那么只能是写两个 CRON 表达式。
常用表达式例子


定时任务
在主程序类上加上 @EnableScheduling,会去自动扫描带有 @Scheduled 注解的定时任务
java
@SpringBootApplication
@EnableScheduling
public class StudyApplication {
public static void main(String[] args) {
SpringApplication.run(StudyApplication.class, args);
}
}
此处,就会开启一个定时任务,注意,需要在类上加上 @Component 组件
java
@Component
public class ScheduledTask {
@Scheduled(fixedRate = 3000)
public void scheduledTask() {
System.out.println("time: " + LocalDateTime.now());
}
}
fixedRate 是 long 类型,表示任务执行的间隔毫秒数,上述代码每3秒执行一次
@Scheduled
对于 @Scheduled 的使用可以总结如下
-
@Scheduled(fixedRate = 3000):上一次开始执行时间点之后 3 秒再执行fixedRate表示每次任务开始执行时,至少要等待指定的时间间隔才会开始下次执行。也就是说,每次任务开始时会按固定的时间间隔进行触发,而不考虑任务执行的实际耗时。- 在上次执行开始之后,按指定的间隔时间执行下次任务。
- 任务执行时间不会影响到下次任务的触发,任务可能会在上一个任务还没执行完时开始执行。
-
@Scheduled(fixedDelay = 3000):上一次执行完毕时间点之后 3 秒再执行fixedDelay表示任务执行完毕后,会等待指定的时间间隔再执行下次任务。也就是说,每次任务的间隔时间是从任务 结束 的时间点开始计算。- 每次任务执行完后,等待指定的间隔时间,再开始执行下一次任务。
- 任务执行时间会影响到下一次任务的触发时间,确保任务之间有固定的延迟。
-
@Scheduled(initialDelay = 1000, fixedRate = 3000):第一次延迟1秒后执行,之后按fixedRate的规则每 3 秒执行一次
initialDelay设置的是任务第一次执行的延迟时间。在任务启动时,任务会先等待initialDelay指定的时间,然后开始第一次执行。initialDelay配合fixedRate或fixedDelayinitialDelay设置任务的首次执行的延迟时间。- 只影响第一次执行,后续的执行间隔由
fixedRate或fixedDelay决定。
-
@Scheduled(cron="0 0 2 1 * ? *"):通过cron表达式定义规则