一、基于注解的定时
基于注解的定时任务,需要使用到的注解有 @Configuration @EnableScheduling @Scheduled
其中前两个注解作用在类上,标记为一个配置类和开启定时任务。@Scheduled 注解作用在方法上,指定定时执行的内容,其中参数包括:
- cron 设置定时执行的表达式
- zone 执行时间区域
- fixedDelay 和 fixedDelayString 表示固定延迟时间,上个任务完成后,延长多久执行
- fixedRate 和 fixedRateString 表示固定频率,上个任务开始后,多长时间后开始执行
- initialDelay 和 initialDelayString 表示初始延迟时间,第一次被调用前延迟的时间
1.cron 表达式格式
{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可省略)}
序号 | 说明 | 必填 | 允许填写的值 | 允许的通配符 |
---|---|---|---|---|
1 | 秒 | 是 | 0-59 | , - * / |
2 | 分 | 是 | 0-59 | , - * / |
3 | 时 | 是 | 0-23 | , - * / |
4 | 日 | 是 | 1-31 | , - * ? / L W |
5 | 月 | 是 | 1-12 / JAN-DEC | , - * / |
6 | 周 | 是 | 1-7 or SUN-SAT | , - * ? / L # |
7 | 年 | 否 | 1970-2099 | , - * / |
cron 案例
30 * * * * ? 每分钟的30秒触发
30 10 * * * ? 每小时的10分30秒触发
30 10 1 20 * ? 每个月20号1点10分30秒触发任务
30 10 1 20 10 ? 每年10月201点10分30秒触发任务
30 10 1 20 10 ? 2020 代表2020年10月20 1点10分30秒触发任务
30 10 1 ? 10 * 2020 代表2020年10月每天1点10分30秒触发任务
30 10 1 ? 10 SUN 2020 代表2020年10月每周日1点10分30秒触发任务
15,30,45 * * * * ? 每15秒 30 秒 45 秒都会触发任务
15-45 * * * * ? 15-45秒内,每秒都会触发任务
15/5 * * * * ? 每分钟的15秒开始触发,每隔5秒触发一次
15-30/5 * * * * ? 每分钟的15 - 30 秒之间触发,每隔5秒触发一次
15-45 * * * * ? 15-45 秒内,每秒都会触发任务
0 0/3 * * * ? 没小时开始,每隔三分钟触发一次
0 15 10 ? * MON-FRI 星期1到星期5 的10点15分0秒触发任务
0 15 10 L * ? 每月最后一天的10点15分0秒触发任务
0 15 10 ? * 5L每个月的最后一个星期4的10点15分0秒触发
0 15 10 ? * 5#3 每个月的第三周的星期4 的10点15分0秒触发任务
参考:https://www.cnblogs.com/xiang--liu/p/11378860.html
二、动态定时任务
@Slf4j @Configuration @EnableScheduling @ConditionalOnProperty(value = "task.enable.dynamic",havingValue = "true") public class DynamicScheduleTask implements SchedulingConfigurer { @Autowired private UserDao userDao; /** * 执行定时任务. */ @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask( //1.添加任务内容(Runnable) () -> log.info("执行动态定时任务: " + LocalDateTime.now().toLocalTime()), //2.设置执行周期(Trigger) triggerContext -> { //2.1 从数据库获取执行周期 String cron = userDao.getUserCronStr(1L); //2.2 合法性校验. if (StringUtils.isEmpty(cron)) { // Omitted Code .. } //2.3 返回执行周期(Date) return new CronTrigger(cron).nextExecutionTime(triggerContext); } ); } }
区别是可以通过读取数据库的配置进行动态的调节定时规则
三、开启多线程定时任务
@Slf4j @Component @EnableScheduling @EnableAsync @ConditionalOnProperty(value = "task.enable.multi",havingValue = "true") public class MultithreadScheduleTask { @Async @Scheduled(cron = "0/3 * * * * *") //间隔1秒 public void first() throws InterruptedException { log.info("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + " 线程 : " + Thread.currentThread().getName()); } @Async @Scheduled(cron = "18/1 * * * * *") public void second() { log.info("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + " 线程 : " + Thread.currentThread().getName()); } }