1.1 使用步骤

总共分为两步

第一步:使用@Scheduled注解启用计划任务

第二部:使用 @Scheduled 设置计划任务执行间隔时间

fixedRate: 执行频率(以上一次执行的起始时间来计算下一次的执行时间),取值为long数值,以毫秒为单位

cron: cron表达式

1.2 cron表达式

image-20240126220133001

注意:在springboot中cron表达式无法用Year

西方习惯将星期日作为第一天,星期六作为最后一天

2.1 通用符号:,- * /

: 表示列出枚举值。例如:在Minutes域使用5,20,表示在时间的分钟数为5、20时触发事件

**- **: 表示范围。例如在Minutes域使用5-20,表示在时间的分钟数为5到20时每分钟都触发事件

*** **: 表示匹配该域的任意值。假如在Minutes域使用*,表示时间分钟数不做限制,每分钟都触发事件

/ : 表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes:域使用5/20,表示时间的分钟数
为5时触发一次,后隔20分钟即25、45再分别触发一次事件

2.2 专用符号:? L W LW # C

专有符号中除 ?外,在Spring定时任务中都不支持!

? : 只能用在DayofMonth和DayofWeeki两个域,由于DayofMontha和DayofWeek互斥,须对其一设置?
L : 表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeeki域使用5L,意味着在最后的
一个星期四触发
W : 表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日
触发事件,既可能在设置的日期前也可能在后
LW : 这两个字符可以连用,表示在某个月最后一个工作日
# : 用于确定每个月第几个星期几,只能出现在DayofWeek域。例如在4#2,表示某月的第二个星期三

:只能用在DayofMonth和DayofWeek两个域,需要关联日历,如果没关联可以忽略。

1.3 异步多线程定时任务

默认是单线程的定时任务,如果任务持续时间较长,就会将后续定时任务拖延,导致丢失任务

两步实现:

  1. 开启异步注解 : @EnableAsync
  2. 设置异步执行 : @Async

相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.shiguang.schedule;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.text.DateFormat;
import java.util.Date;

@EnableScheduling
@EnableAsync
@SpringBootApplication
public class ScheduleApplication {

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



@Async
// @Scheduled(fixedRate = 2 * 60 * 1000)
// @Scheduled(cron = "0 0/30 9-22 * * ?")
@Scheduled(fixedRate = 10 * 1000)
public void printTime1(){
System.out.println("Thread:"+Thread.currentThread().getName());
System.out.println("printTime1:"+ DateFormat.getDateInstance().format(new Date()));
}

@Async
@Scheduled(fixedRate = 30 * 1000)
public void printTime2(){
System.out.println("Thread:"+Thread.currentThread().getName());
System.out.println("printTime2:"+ DateFormat.getDateInstance().format(new Date()));
}

}

springboot定时任务

在线生成cron表达式