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 中 實現多線程定時任務的三種方案,你喜歡哪一種?

到此這篇關於Spring Boot多個定時任務阻塞問題解決的文章就介紹到這瞭,更多相關SpringBoot多定時任務阻塞內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: