这两天碰到一个问题,定时任务一直没有执行,找了很久,最终发现是这个定时器的资源其他定时器抢占了,导致这个定时器一直没有执行上。总结一下我遇到过的几种定时器没有按时执行的原因。

配置错误

  • 没有在配置类上加上@EnableScheduling注解

  • 带有@EnableScheduling注解的类没有通过@Configuratioin注解注入Spring

  • 定时器没有注入Spring

定时器执行时间过长

定时器执行一个任务时,必须等待上个任务执行完成,才能继续执行。假设一个定时器每10s执行一次,但是定时器里的任务需要15s才能执行完成,那么下一次任务会在啥时候执行呢?答案是20s之后,10s + 10s。

定时器资源抢夺

SpringBoot的定时器任务默认是同步执行的,如果一个定时器任务A正在执行,此时另一个任务B也到了执行时间,那么任务B将不会执行。等待任务A执行完成后,再根据定时器的时间设置,执行相应的定时任务。

解决的方案就是添加线程池,让各个定时器的任务分别执行,互不干扰,需要再yml文件中添加如下配置:

spring:
  task:
    scheduling:
      # 设置任务调度线程名称前缀
      thread-name-prefix: task-schedule-
      # 设置任务调度线程池大小
      pool:
        size: 10
      # 设置任务调度线程池关闭时等待所有任务完成
      shutdown:
        await-termination: true