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通过配置来开关

在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐