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