一、静态:基于注解
@Scheduled
,基于注解的任务是单线程,当开启多个任务时,任务的执行时机会受到上一个任务执行时间的影响。
1.创建定时器
@Component //1.自动注入
@Configuration //主要用于标记配置类,兼备Component的效果(自动注入)
@EnableScheduling //2.开启定时任务,没有此注解则不会执行
public class StaticScheduleTask {
@Scheduled(cron = "0/5 * * * * ?")
//等效于设置fixedRate = 5000, 每隔5秒
//@Scheduled(fixedRate = 5000)
private void task() {}
}
*如果在@SpringBootApplication
的启动类注解了@EnableScheduling
,那么SpringBoot会在包扫描时,注入定时类的同时开启了该类的定时任务。
2.Corn表达式
59 59 23 * * ? //每天的23:59:59
9,19,29 * * * * ? //在第9、19、29秒时
0 0/30 9-18 * * ? //在每天9-18点的每隔30分钟
0 30 18 ? * 5 //每周四的18:30
0 0 9 * L ? //每月最后一天的9点
0 0 9 * 6L ? //每个月的倒数第6天的9点
0 0 9 ? * FRI#3 //第3个周五天的9点
- 秒(0~59)
- 分(0~59)
- 时(0~23)
- 日(0~31),根据月份不同日期最大范围不同
- 月(0~11)
- 周几(1~7, SUN/MON/TUE/WED/THU/FRI/SAT)
- ~~年(19702099)~
每个项可以是:
- 一个值,比如6
- 一个区间,比如9-12
- 一个间隔时间,比如0/4,每4秒
- 一个集合,比如1,3,5
*注意:天
与周几
是互斥的,当一个有值时,另一个为?
*从Spring4.x版本后,不再进行年份的支持
*Corn表达式是灵活的配置方式,也可以使用fixedDelay
延迟启动毫秒数和fixedRate
固定的间隔毫秒数
二、动态:基于接口
SchedulingConfigurer
,应用场景:想要从数据库中读取指定时间来动态执行任务。
1.TaskScheduler线程池
在项目中,有可能会定义开启多个定时任务。多个定时任务之间是相互独立且并行的。
在Spring中,是默认创建的一个单线程池的,这对于多任务调度,并发执行时会有时间偏移。
2.自定义线程池
@Configuration //1.自动注入
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(taskExecutor());
}
@Bean
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(20);
}
}
三、多线程定时任务(基于注解)
1.创建多线程
@Component //1.自动注入
@EnableScheduling //2.开启任务
@EnableAsync //3.开启异步
public class MutilThreadScheduleTask {
@Async
@Scheduled(fixedDelay = 1000)
public void firstThread() {}
@Async
@Scheduled(fixedRate = 2000)
public void secondThread() {}
}
2.调度配置区别
- fixedDelay=1000 //方法执行完成后,延迟1000ms后再执行
- fixedRate=1000 //方法每隔1000ms的频次执行一次,当方法业务时间超过频次时间,那么需要等待方法完成,之后即刻执行
- corn=“0/1 * * * * ?” //方法每隔1s的频次执行一次,即使业务时间超过频次时间,也即刻执行