1.问题描述
spring boot中多个定时任务如果都在可执行时间,则会存在一个定时任务等待另一个定时任务的现象
2.原因
在spring boot中所有定时任务默认为单线程执行,不同定时任务间相互阻塞
3.测试代码
package com.lmy.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author : liu ming yong
* @date : 2023/6/21 下午 4:00
* spring中多个定时任务如果都在可执行时间,则会存在一个定时任务等待另一个任务的现象
* @description : 尝试解决spring中定时器相互阻塞问题
*/
@Component
public class BlockTask {
@Scheduled(cron = "0/2 * * * * ?")
public void task1() throws InterruptedException {
System.out.println("定时任务1");
Thread.sleep(10000);
}
@Scheduled(cron = "0/2 * * * * ?")
public void task2() {
System.out.println("定时任务2");
}
}
4.未解决时结果
定时任务1
定时任务2
定时任务1
定时任务2
定时任务2
定时任务1
定时任务2
定时任务1
定时任务2
定时任务1
5.解决方法
package com.lmy.config;//package com.crunii.dt.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
/**
* @author : liu ming yong
* @date : 2023/4/15 下午 9:44
* @description : 多线程定时任务,实现每一个定时任务分配一个独立线程
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(30));
}
}
6.处理解决后结果
定时任务2
定时任务1
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务1
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务1
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务2
定时任务1
定时任务2
定时任务2
定时任务2
7.结果分析
- 通过步骤4和6结果对比可知,spring boot定时任务同一时间内执行的多个定时任务存在阻塞,spring boot定时任务默认单线程
- 由步骤6解决后的结果可知,对spring boot定时任务设置多线程后,是对每一个定时任务分配了一个独立线程,而不是每一个执行时间core分配一个线程,这样就保证了一个定时任务内的数据安全,不会出现多个线程执行同一定时任务从而造成线程安全问题(可理解为单个定时任务还是单线程的,没有去改变单个定时任务原有的阻塞特性)