@Scheduled两个整点任务:触发必为整点,执行时间藏着线程池玄机

在同一个类中,两个标注@Scheduled且均配置为"整点执行"的方法,触发时间一定是整点,但实际执行的"开始时间"可能受线程池影响出现延迟,核心结论如下:

1. 触发时间:严格按配置执行(必为整点)

@Scheduled的底层调度器(如ThreadPoolTaskScheduler)会严格按照时间规则(如cron = "0 0 * * * ?")在每个整点触发任务。无论两个方法是否在同一个类,调度器都会在00:00、1:00、2:00... 同时向这两个任务发出"执行信号"。

这一步由Spring的定时任务框架保证,与类结构、方法数量无关。

2. 执行时间:可能延迟,取决于线程池配置

任务"触发"后,实际开始执行的时间由调度器的线程池决定:

(1)默认单线程配置(poolSize = 1

Spring默认的ThreadPoolTaskScheduler线程池大小为1,此时两个任务会串行执行

  • 第一个任务先占用线程开始执行;
  • 第二个任务需等待第一个任务执行完毕后,才能获取线程开始执行。

示例

java 复制代码
@Scheduled(cron = "0 0 * * * ?")
public void task1() {
    System.out.println("task1 开始:" + LocalDateTime.now()); // 00:00:00
    try { Thread.sleep(5000); } catch (InterruptedException e) {} // 耗时5秒
}

@Scheduled(cron = "0 0 * * * ?")
public void task2() {
    System.out.println("task2 开始:" + LocalDateTime.now()); // 00:00:05(延迟5秒)
}

结果:两个任务都在00:00被触发,但task2因等待线程,实际开始时间延迟至00:00:05。

(2)多线程配置(poolSize ≥ 2

若手动配置线程池大小≥2,两个任务可并行执行,同时在整点开始:

java 复制代码
// 配置线程池
@Bean
public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setPoolSize(2); // 2个线程
    return scheduler;
}

// 任务执行结果:
// task1 开始:00:00:00
// task2 开始:00:00:00

3. 关键结论

  • 触发时间 :必为整点(由@Scheduled的时间规则严格保证)。
  • 执行时间
    • 单线程:后执行的任务会延迟(等待前一个任务释放线程)。
    • 多线程:若线程池有足够空闲线程,两个任务会在整点同时开始执行。

若业务要求"必须在整点同时执行",需配置足够的线程池大小(poolSize ≥ 任务数量)。

相关推荐
南风知我意95732 分钟前
【前端面试3】初中级难度
前端·javascript·面试
知识即是力量ol32 分钟前
在客户端直接上传文件到OSS
java·后端·客户端·阿里云oss·客户端直传
华清远见成都中心37 分钟前
GPIO(通用输入输出)面试中高频问题
单片机·面试·职场和发展
闻哥39 分钟前
深入理解 Spring @Conditional 注解:原理与实战
java·jvm·后端·python·spring
qq_256247052 小时前
Google 账号防封全攻略:从避坑、保号到申诉解封
后端
MX_93592 小时前
使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描
java·后端·spring
弹简特2 小时前
【JavaEE05-后端部分】使用idea社区版从零开始创建第一个 SpringBoot 程序
java·spring boot·后端
爬山算法2 小时前
Hibernate(81)如何在数据同步中使用Hibernate?
java·后端·hibernate
Ivanqhz3 小时前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
Loo国昌3 小时前
【大模型应用开发】第三阶段:深度解析检索增强生成(RAG)原理
人工智能·后端·深度学习·自然语言处理·transformer