使用SpringBoot创建定时任务非常简单,只需在添加几个注解就可以实现定时任务。
@Component
@EnableScheduling //在启动类上注解也可以
public class TestJob {
@Scheduled(cron = "0/10 * * * * ?")
public void task1(){
System.out.println("----任务一----");
}
@Scheduled(fixedRate = 1000 * 10)
public void task2(){
System.out.println("----任务二----");
}
@Scheduled(fixedDelay=1000)
public void task3(){
System.out.println("----任务三----");
}
}
在上面的定时任务中,我们在方法上使用@Scheduled注解来设置任务的执行时间,并且使用三种属性配置方式:
- fixedRate:间隔时间是根据上次任务开始的时候计时的
- fixedDelay:间隔时间是根据上次的任务结束的时候开始计时的
- cron:通过表达式来配置任务执行时间
cron表达式详解
一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。按顺序依次为:
- 秒(0~59) 例如0/5表示每5秒
- 分钟(0~59)
- 小时(0~23)
- 日(0~31)的某天,需计算
- 月(0~11)
- 周几( 可填1-7 或 SUN/MON/TUE/WED/THU/FRI/SAT)
- 年份(1970-2099)
一些表达式案例:
- “0 0 10,14,16 * * ?” 每天上午10点,下午2点,4点
- “0 0/30 9-17 * * ?” 每天早上9点到晚上5点每半小时
- “0 0 12 ? * WED” 表示每个星期三中午12点
- “0 15 10 * * ?” 每天上午10:15触发
- “0 15 10 * * ? 2005” 2005年的每天上午10:15触发
- “0 * 14 * * ?” 在每天下午2点到下午2:59期间的每1分钟触发
- “0 0/5 14 * * ?” 在每天下午2点到下午2:55期间的每5分钟触发
- “0 0/5 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
- “0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
- “0 10,44 14 ? 3 WED” 每年三月的星期三的下午2:10和2:44触发
- “0 15 10 ? * MON-FRI” 周一至周五的上午10:15触发
- “0 15 10 15 * ?” 每月15日上午10:15触发
- “0 15 10 L * ?” 每月最后一日的上午10:15触发0:15触发
- “0 15 10 ? * 6L 2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发
- “0 15 10 ? * 6#3” 每月的第三个星期五上午10:15触发
spring的定时任务默认是单线程的,不会开启另一条线程去执行任务,如果有多个任务需要等待上一个任务执行完成后,再去执行下一个任务。下面我们添加一个类来实现多线程并行执行任务,只要到了执行时间,不需要等待其它任务执行完毕就可以开始执行任务。
package com.instudio.ebay.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(20);
}
}
只需添加上面的,就可以实现多个任务并行。