Spring Task-定时任务
步骤1:在springboot启动类上添加注解
在Spring boot启动类上添加注解:@EnableScheduling 开启扫描并执行异步任务
步骤2:编写任务类
//异步定时任务类
@Component
public class ChooseCourseTask {
public static final Logger LOGGER = LoggerFactory.getLogger(ChooseCourseTask.class);
// @Scheduled(fixedRate = 5000) //上次执行开始时间后5秒执行
//@Scheduled(fixedDelay = 5000) //上次执行完毕后5秒执行
//@Scheduled(initialDelay = 3000, fixedRate = 5000) //第一次延迟3秒,以后每隔5秒执行一次
//@Scheduled(cron = "0/3 * * * * *")//每隔3秒执行一次
public void task1() {
LOGGER.info("============测试定时任务1开始==============");
try {
for (int i = 0; i < 5; i++) {
LOGGER.info("============测试定时任务1执行" + (i + 1));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("============测试定时任务1结束==============");
}
}
注解属性:
// @Scheduled(fixedRate = 5000) //上次执行开始时间后5秒执行
//@Scheduled(fixedDelay = 5000) //上次执行完毕后5秒执行
//@Scheduled(initialDelay = 3000, fixedRate = 5000) //第一次延迟3秒,以后每隔5秒执行一次
//@Scheduled(cron = “0/3 * * * * *”)//每隔3秒执行一次
cron表达式
cron表达式包括6部分:
秒(0~59)
分钟(0~59)
小时(0~23)
月中的天(1~31)
月(1~12)
周中的天
(填写MON,TUE,WED,THU,FRI,SAT,SUN,或数字1~7 1表示MON,依次类推)
特殊字符介绍:
“/”字符表示指定数值的增量
“*”字符表示所有可能的值
“-”字符表示区间范围
“,” 字符表示列举
“?”字符仅被用于月中的天和周中的天两个子表达式,表示不指定值
例子:
0/3 * * * * * 每隔3秒执行
0 0/5 * * * * 每隔5分钟执行
0 0 0 * * * 表示每天0点执行
0 0 12 ? * WEN 每周三12点执行
0 15 10 ? * MON-FRI 每月的周一到周五10点 15分执行
0 15 10 ? * MON,FRI 每月的周一和周五10点 15分执行
串行任务测试
参考 task1方法的的定义方法,再定义task2方法,此时共用两个任务方法。
@Scheduled(cron = "0/3 * * * * *")//每隔3秒执行一次
public void task2() {
LOGGER.info("============测试定时任务2开始==============");
try {
for (int i = 0; i < 5; i++) {
LOGGER.info("============测试定时任务2执行" + (i + 1));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("============测试定时任务2结束==============");
}
结果:
通过测试发现,两个任务方法由一个线程串行执行,task1方法执行完成task2再执行。
2020-06-14 16:40:45.098 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行1
2020-06-14 16:40:46.098 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行2
2020-06-14 16:40:47.099 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行3
2020-06-14 16:40:48.100 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行4
2020-06-14 16:40:49.100 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行5
2020-06-14 16:40:50.101 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1结束==============
2020-06-14 16:40:50.101 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2开始==============
2020-06-14 16:40:50.101 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行1
2020-06-14 16:40:51.101 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行2
2020-06-14 16:40:52.102 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行3
2020-06-14 16:40:53.102 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行4
2020-06-14 16:40:54.103 [pool-10-thread-1] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行5
Spring Task并行任务
配置异步任务
创建异步任务配置类,需要配置线程池实现多线程调度任务。
@Configuration
@EnableScheduling
public class AsyncTaskConfig implements SchedulingConfigurer, AsyncConfigurer {
//线程池线程数量
private int corePoolSize = 5;
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.initialize();//初始化线程池
scheduler.setPoolSize(corePoolSize);//线程池容量
return scheduler;
}
@Override
public Executor getAsyncExecutor() {
Executor executor = taskScheduler();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setTaskScheduler(taskScheduler());
}
}
将@EnableScheduling添加到此配置类上,SpringBoot启动类上不用再添加@EnableScheduling
测试
通过测试发现两个任务由不同的线程在并行执行,互不影响。
2020-06-14 16:50:07.002 [taskScheduler-4] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行2
2020-06-14 16:50:08.002 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行3
2020-06-14 16:50:08.002 [taskScheduler-4] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行3
2020-06-14 16:50:09.003 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行4
2020-06-14 16:50:09.003 [taskScheduler-4] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行4
2020-06-14 16:50:10.003 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行5
2020-06-14 16:50:10.003 [taskScheduler-4] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行5
2020-06-14 16:50:11.004 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2结束==============
2020-06-14 16:50:11.004 [taskScheduler-4] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1结束==============
2020-06-14 16:50:12.001 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2开始==============
2020-06-14 16:50:12.001 [taskScheduler-2] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1开始==============
2020-06-14 16:50:12.001 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行1
2020-06-14 16:50:12.001 [taskScheduler-2] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行1
2020-06-14 16:50:13.002 [taskScheduler-3] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务2执行2
2020-06-14 16:50:13.002 [taskScheduler-2] INFO c.x.order.task.ChooseCourseTask - ============测试定时任务1执行2