Spring Boot 如何解決多個定時任務阻塞問題?
最近長文擼多了,有點累,今天來點簡單的。
今天這篇文章介紹一下Spring Boot 中 如何開啟多線程定時任務?
為什么Spring Boot 定時任務是單線程的?
想要解釋為什么,一定要從源碼入手,直接從@EnableScheduling這個注解入手,找到了這個ScheduledTaskRegistrar類,其中有一段代碼如下:
- protected void scheduleTasks() {
- if (this.taskScheduler == null) {
- this.localExecutor = Executors.newSingleThreadScheduledExecutor();
- this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
- }
- }
如果taskScheduler為null,則創建單線程的線程池:Executors.newSingleThreadScheduledExecutor()。
多線程定時任務如何配置?
下面介紹三種方案配置多線程下的定時任務。
1、重寫SchedulingConfigurer#configureTasks()
直接實現SchedulingConfigurer這個接口,設置taskScheduler,代碼如下:
- @Configuration
- public class ScheduleConfig implements SchedulingConfigurer {
- @Override
- public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
- //設定一個長度10的定時任務線程池
- taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
- }
- }
2、通過配置開啟
Spring Boot quartz 已經提供了一個配置用來配置線程池的大小,如下;
- spring.task.scheduling.pool.size=10
只需要在配置文件中添加如上的配置即可生效!
3、結合@Async
@Async這個注解都用過,用來開啟異步任務的,使用@Async這個注解之前一定是要先配置線程池的,配置如下:
- @Bean
- public ThreadPoolTaskExecutor taskExecutor() {
- ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
- poolTaskExecutor.setCorePoolSize(4);
- poolTaskExecutor.setMaxPoolSize(6);
- // 設置線程活躍時間(秒)
- poolTaskExecutor.setKeepAliveSeconds(120);
- // 設置隊列容量
- poolTaskExecutor.setQueueCapacity(40);
- poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
- // 等待所有任務結束后再關閉線程池
- poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
- return poolTaskExecutor;
- }
然后在@Scheduled方法上標注@Async這個注解即可實現多線程定時任務,代碼如下:
- @Async
- @Scheduled(cron = "0/2 * * * * ? ")
- public void test2() {
- System.out.println("..................執行test2.................");
- }
總結
本篇文章介紹了Spring Boot 中 實現多線程定時任務的三種方案,你喜歡哪一種?