前言在使用Springboot整合定时任务,发现当某个定时任务执行出现执行时间过长的情况时会阻塞其他定时任务的执行。问题定位后续通过翻查Springboot的文档以及打印日志(输出当前线程信息)得知问题是由于Springboot默认使用只要1个线程处理定时任务。问题复盘需要注意示例的Springboot版本为2.1.3.RELEASE。关键pom文件配置 <!–继承父项目–> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> …省略非关键配置 <!– 引入依赖–> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>定时任务import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;/** * 定时任务 * @author RJH * create at 2019-03-29 /@Componentpublic class SimpleTask { private static Logger logger= LoggerFactory.getLogger(SimpleTask.class); /* * 执行会超时的任务,定时任务间隔为5000ms(等价于5s) / @Scheduled(fixedRate = 5000) public void overtimeTask(){ try { logger.info(“current run by overtimeTask”); //休眠时间为执行间隔的2倍 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } /* * 正常的定时任务 / @Scheduled(fixedRate = 5000) public void simpleTask(){ logger.info(“current run by simpleTask”); }}启动类import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication@EnableSchedulingpublic class TaskDemoApplication { public static void main(String[] args) { SpringApplication.run(TaskDemoApplication.class, args); }}运行结果…省略非关键信息2019-03-29 21:22:38.410 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask2019-03-29 21:22:38.413 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask2019-03-29 21:22:48.413 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask2019-03-29 21:22:48.414 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask2019-03-29 21:22:58.418 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask2019-03-29 21:22:58.418 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask2019-03-29 21:23:08.424 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask2019-03-29 21:23:08.424 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask2019-03-29 21:23:18.425 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask2019-03-29 21:23:18.426 INFO 59731 — [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask…结果分析由运行结果可以看出:每次定时任务的运行都是由scheduling-1这个线程处理正常运行的simpleTask被overtimeTask阻塞导致了运行间隔变成了10秒后面通过查阅Springboot的文档也得知了定时任务默认最大运行线程数为1。解决方案由于使用的Springboot版本为2.1.3.RELEASE,所以有两种方法解决这个问题使用Springboot配置在配置文件中可以配置定时任务可用的线程数:## 配置可用线程数为10spring.task.scheduling.pool.size=10自定义定时任务的线程池使用自定义的线程池代替默认的线程池import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;/* * 定时任务配置类 * @author RJH * create at 2019-03-29 /@Configurationpublic class ScheduleConfig { /* * 此处方法名为Bean的名字,方法名无需固定 * 因为是按TaskScheduler接口自动注入 * @return */ @Bean public TaskScheduler taskScheduler(){ // Spring提供的定时任务线程池类 ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler(); //设定最大可用的线程数目 taskScheduler.setPoolSize(10); return taskScheduler; }}