文章目录
- 一、为什么需要配置多线程定时任务
- 二、单线程定时任务
- 三、多线程定时任务
一、为什么需要配置多线程定时任务
springboot中通过注解 @Scheduled 注解的方法都是一个定时执行的任务, 默认都是单线程的,就算是多个定时任务也是在同一个单线程(scheduled-1)中运行, 如果其中某一个定时任务产生了阻塞,那么会导致项目中其他所有的定时任务线程都不执行。后果非常严重,故而需要配置多线程定时任务。
二、单线程定时任务
导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
创建定时任务
@Slf4j
@Component
public class ScheduledService {
/**
* fixedRate:定义一个按一定频率执行的定时任务
* fixedDelay:定义该任务延迟执行时间。
* cron:通过表达式来配置任务执行时间
*/
@Scheduled(cron = "0/5 * * * * *")
public void scheduled(){
log.info("=====>>>>>使用cron {}",System.currentTimeMillis());
}
@Scheduled(fixedRate = 5000)
public void scheduled1() {
log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
}
@Scheduled(fixedDelay = 5000)
public void scheduled2() {
log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
}
}
在主类上使用@EnableScheduling注解开启对定时任务的支持,然后启动项目
@SpringBootApplication
@EnableScheduling
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class,args);
}
}
可以看到三个定时任务都已经执行,并且使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。
三、多线程定时任务
在SpringBoot项目中一般使用config配置类的方式添加配置,所以新建一个AsyncConfig类。
@Configuration
@EnableAsync
public class AsyncConfig {
/*
*此处成员变量应该使用@Value从配置中读取
*/
private int corePoolSize = 10;
private int maxPoolSize = 200;
private int queueCapacity = 10;
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.initialize();
return executor;
}
}
然后在定时任务的类或者方法上添加@Async
@Slf4j
@Component
public class ScheduledService {
/**
* fixedRate:定义一个按一定频率执行的定时任务
* fixedDelay:定义该任务延迟执行时间。
* cron:通过表达式来配置任务执行时间
*/
@Async
@Scheduled(cron = "0/5 * * * * *")
public void scheduled(){
log.info("=====>>>>>使用cron {}",System.currentTimeMillis());
}
@Async
@Scheduled(fixedRate = 5000)
public void scheduled1() {
log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
}
@Async
@Scheduled(fixedDelay = 5000)
public void scheduled2() {
log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
}
}