10_Spring Boot 中的 @Scheduled 注解是单线程还是多线程?同步还是异步?
🔟 10_Spring Boot 中的 @Scheduled
注解是单线程还是多线程?同步还是异步?
✅ 结论先行
Spring Boot 中的 @Scheduled
注解默认是 单线程且同步执行 的。
这意味着:
如果你定义了多个使用 @Scheduled
注解的定时任务,它们会共用一个线程顺序执行。一旦其中某个任务执行时间较长或发生异常,可能会阻塞其他定时任务的正常调度!
✅ 如何解决:将定时任务配置为多线程执行
为了让定时任务支持并发执行(多线程),可以采用以下三种方式之一:
✅ 方式一:定义 TaskScheduler
Bean
@Configuration
public class ScheduleConfig {@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();// 设置线程池大小(建议:CPU 核心数 * 2)scheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);return scheduler;}}
✅ 方式二:实现 SchedulingConfigurer
接口配置线程池
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler(new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2));}
}
✅ 方式三:通过配置文件开启多线程支持(Spring Boot 2.1+)
spring:task:scheduling:pool:size: 8 # 设置定时任务线程池大小
⚠️ 注意:该方式依赖 Spring Boot 的自动配置机制,适用于较新版本。
✅ 如果希望定时任务异步执行怎么办?
多线程 ≠ 异步。如果你希望某个定时任务在调度后立即返回,由独立线程异步执行,可以启用 Spring 的异步机制:
步骤一:在启动类上添加 @EnableAsync
注解
@SpringBootApplication
@EnableAsync
public class Application {// ...
}
步骤二:在定时任务方法上添加 @Async
注解
@Scheduled(cron = "0 */1 * * * ?")
@Async
public void runTask() {// 异步执行的任务逻辑
}
✅ 总结
问题 | 默认行为 | 推荐配置方式 |
---|---|---|
是否单线程执行? | 是(共用一个线程) | 使用线程池配置为多线程 |
是否同步执行? | 是(方法阻塞) | 使用 @Async 异步注解 |
是否可以自定义线程数? | 否 | 配置 TaskScheduler 或 YAML 文件 |