一、概述
@EnableScheduling
配置在配置类上,表示对定时任务的支持
@Scheduled
配置在方法上,声明需要执行定时任务的方法
二、@Scheduled
参数
- zone表示执行时间时区
- initialDelay 和initialDelayString表示初始延迟时间,第一次被调用前延迟的时间
- fixedRate 和fixedRateString表示固定频率,上个任务开始后,多长时间后开始执行
- fixedDelay 和fixedDelayString 表示固定延迟时间,上个任务完成后,延迟多长时间执行
- cron是设置定时执行的表达式,表达式对应含义:second、minute、hour、day of month、month、day of week,代表秒、分、时、日、月、星期
三、cron 表达式
如: * */5 * * * SUN-MON
周一至周五每隔5分钟执行一次
可用"-"表示范围;""表示所有的值,其中day of month (日) 和day of week (星期),表达式包含"?"时,整个表达式会被直接替换为""
- second:值可为0到59
- minute:值可为0到59
- hour:值可为0到23
- day of month:值可为1到31,可用"-"表示范围
- month:值可以1到12,或JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC
- day of week:值可为0到6,或SUN(0, 7),MON,TUE,WED,THU,FRI,SAT
四、栗子
pom文件:
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
代码:
@Configuration
@EnableScheduling
public class SchedulingConfig {
/**
* 配置 taskScheduler,多线程执行多个任务;
* 如果不配置taskScheduler,默认使用的是容量为1的线程池
*/
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setThreadNamePrefix("my-task-scheduler-");
taskScheduler.setPoolSize(10);
return taskScheduler;
}
@Scheduled(initialDelay = 3000, fixedRate = 5000)
public void fixedRate() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s ===>初始延迟3s,每隔5s", threadName));
}
@Scheduled(fixedDelay = 5000)
public void fixedDelay() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s ==>每次执行完延迟5秒", threadName));
}
@Scheduled(cron = "5 * * * * *")
public void second1() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s ===>在5s的时候执行", threadName));
}
@Scheduled(cron = "*/5 * * * * *")
public void second2() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s ===>每5s执行一次", threadName));
}
}
五、原理
任务会被注册到org.springframework.scheduling.config.ScheduledTaskRegistrar
默认会创建线程池Executors.newSingleThreadScheduledExecutor()
,其容量为1,所以默认就一个线程执行任务
如果需要多线程执行多个任务,需要配置 TaskScheduler