1. マルチスレッドのスケジュールされたタスクを構成する必要があるのはなぜですか
springboot で @Scheduled アノテーションが付けられたメソッドは、スケジュールされた実行タスクです。デフォルトでは、シングルスレッドです。複数のスケジュールされたタスクであっても、同じ単一スレッド (scheduled-1) で実行されます。スケジュールされたタスクの 1 つがブロックされると、すべてのスケジュールされたタスクが実行されます。プロジェクト内の他のスケジュールされたタスク スレッドは実行されません。結果は非常に深刻であるため、マルチスレッドのタイミング タスクを構成する必要があります。
2. シングルスレッドタイミングタスク
导入依赖
<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);
}
}
スケジュールされたタスクが 3 つ実行されており、同じスレッド内で直列に実行されていることがわかります。スケジュールされたタスクが 1 つだけの場合は、そのまま実行しても問題ありません。スケジュールされたタスクの数が増加した場合、1 つのスケジュールされたタスクが実行されます。タスクがスタックすると、他のタスクが失敗する原因になります。
3. マルチスレッドタイミングタスク
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());
}
}