10_Spring Boot 中的 @Scheduled 注解是单线程还是多线程?同步还是异步?

🔟 10_Spring Boot 中的 @Scheduled 注解是单线程还是多线程?同步还是异步?

✅ 结论先行

Spring Boot 中的 @Scheduled 注解默认是 单线程且同步执行 的。

这意味着:

如果你定义了多个使用 @Scheduled 注解的定时任务,它们会共用一个线程顺序执行 。一旦其中某个任务执行时间较长或发生异常,可能会阻塞其他定时任务的正常调度


✅ 如何解决:将定时任务配置为多线程执行

为了让定时任务支持并发执行(多线程),可以采用以下三种方式之一:


✅ 方式一:定义 TaskScheduler Bean

复制代码
@Configuration
public class ScheduleConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        // 设置线程池大小(建议:CPU 核心数 * 2)
        scheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);
        return scheduler;
    }

}

✅ 方式二:实现 SchedulingConfigurer 接口配置线程池

复制代码
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

    @Override
    public 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 文件