场景:
每日凌晨要执行两个定时任务,分别属于两个业务。有一个业务的定时任务执行时间较长,该任务没执行完之前不能重复执行(事务)。即业务与业务之间并行,任务本身串行。
技术栈:
采用spring自带的定时任务schedule
问题:
schedule本身是所有定时任务都串行。原因如下图所示,默认情况下核心线程池为1
解决方案:
// 配置并发线程池,注意这里的数量应该对应同一时间段可能发生的最大并发任务,比如说凌晨有两个任务要执行。
// 如果一个时间段内只有一个任务执行,哪怕有三个任务,这里也应该是1,比如,凌晨一个任务,中午一个任务,傍晚一个任务,虽然有三个,但是不存在并发
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
@EnableScheduling
public class ScheduleConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler(){
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
// 配置并发线程池,注意这里的数量应该对应同一时间段可能发生的最大并发任务,比如说凌晨有两个任务要执行。
// 如果一个时间段内只有一个任务执行,哪怕有三个任务,这里也应该是1,比如,凌晨一个任务,中午一个任务,傍晚一个任务,虽然有三个,但是不存在并发
// 合理配置不要浪费资源
scheduler.setPoolSize(2);
scheduler.setThreadNamePrefix("scheduled-task-");
return scheduler;
}
}
实例验证:
结果就不撸了啊,自己去跑
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class Job1 {
@Scheduled(cron = "0/2 * * * * ?")
private void t1(){
log.info("t1");
try {
Thread.sleep(8000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
@Scheduled(cron = "0/2 * * * * ?")
public void t2(){
log.info("t2");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}