Spring Boot @Scheduled 是同步还是异步,单线程还是多线程?
@schedule刚开始用的时候回遇到一些坑,主要就是他的同步、异步、多线程的配置问题,这篇文章介绍了@schedule的使用方法,读者遇到问题时可以参考下。
1. 问题
@schedule注解默认是同步且单线程的,如果定时任务比较多或者有的定时任务比较耗时,会影响到其他定时任务的执行
@Component
public class TestSchedule {
public static int i = 0;
@Scheduled(cron = "* * * * * ?")
public void test() throws InterruptedException {
System.out.println(i++);
Thread.sleep(1000 * 100);
}
}
2. 解决方法
我们可以通过以下三种方法将其配置为多线程模式:
第一种: 增加配置类
两种方式:
@Configuration
public class ScheduleConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
//核心线程池数量,方法: 返回可用处理器的Java虚拟机的数量。
taskScheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);
return taskScheduler;
}
}
@Configuration
public class ScheduleConfig1 implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setScheduler(
new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2)
);
}
}
第二种:配置文件添加task配置
spring:
task:
scheduling:
pool:
size: 8 #配置Scheduled定时任务为多线程
通过以上配置,每个任务就变成独立线程,单独执行。但对于单个任务,其仍为同步的,只有该次运行完,才会运行下一次定时任务。如果想把其变为异步任务,可开启异步方法。该方法会导致,同一个任务,即使上一次执行还未完成,只要时间到,就会再次执行该任务
第三种:异步配置
@EnableAsync // 开启异步
@Async
@Scheduled(cron = "* * * * * ?")
public void test() throws InterruptedException {
System.out.println("TEST1 ==== " + i++);
Thread.sleep(1000 * 100);
}
参考:
https://blog.csdn.net/bblzjp/article/details/128216426