springboot项目中定时任务注解@Scheduled未按cron表达式执行
- 背景
 - 问题复现
 - 原因分析
 - 解决方法
 - 其他原因
 
背景
在将一个类注入到ioc后,其中定义了几个定时任务,分别是每隔十秒执行一次,但实际情况却是半小时才执行一次,故开始分析原因:spring scheduled默认为单线程,导致任务阻塞,很多时候不能按时执行原因
问题复现
这是正常情况下,各定时任务正常调度
 
 为其中一个任务加上睡眠3分钟,发现所有的任务在睡眠期间均不会被执行
 
 等待3分钟之后,其他任务均会被执行一次,再次进入等待;也就是说 其中一个任务未执行完毕,其他任务均不会被执行了
 
原因分析
将执行任务的线程打印,发现执行任务的线程均为scheduling-1
 
 而当其中一个任务耗时或睡眠后,其他任务也使用这个线程,只能等待
 
解决方法
方法1- 让此方法异步处理,可以新开线程池异步 - Spring Boot 2.0 以前的实现方式
定义一个新的线程池,为耗时的线程使用,线程参数看项目调整

 不推荐直接使用@Async让耗时方法异步,因其不可控
 
 看看现在的效果,发现即便是任务2耗时,但不影响其他三个任务,而任务2本身的线程池可自行调整核心线程数与拒绝策略

方法2- 只需要修改配置(Spring Boot 2.1以后版本)
spring:
  task:
	scheduling:
	  pool:
		# 最大线程数,默认是 1
		size: 10
	  # 线程名称前缀,默认是 scheduling-
	  thread-name-prefix: demoScheduling-
 

其他原因
添加注解@Scheduled后,未重启项目
未在启动类或@Configuration类上加@EnableScheduling
任务类上有@ConditionalOnProperty通过配置来开关




















