Spring Boot 如何解決多個(gè)定時(shí)任務(wù)阻塞問(wèn)題?
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??

今天這篇文章介紹一下Spring Boot 中 如何開(kāi)啟多線程定時(shí)任務(wù)?
為什么Spring Boot 定時(shí)任務(wù)是單線程的?
想要解釋為什么,一定要從源碼入手,直接從@EnableScheduling這個(gè)注解入手,找到了這個(gè)ScheduledTaskRegistrar類,其中有一段代碼如下:
protected?void?scheduleTasks()?{
??if?(this.taskScheduler?==?null)?{
???this.localExecutor?=?Executors.newSingleThreadScheduledExecutor();
???this.taskScheduler?=?new?ConcurrentTaskScheduler(this.localExecutor);
??}
}
如果taskScheduler為null,則創(chuàng)建單線程的線程池:Executors.newSingleThreadScheduledExecutor()。
多線程定時(shí)任務(wù)如何配置?
下面介紹三種方案配置多線程下的定時(shí)任務(wù)。
1、重寫(xiě)SchedulingConfigurer#configureTasks()
直接實(shí)現(xiàn)SchedulingConfigurer這個(gè)接口,設(shè)置taskScheduler,代碼如下:
@Configuration
public?class?ScheduleConfig?implements?SchedulingConfigurer?{
????@Override
????public?void?configureTasks(ScheduledTaskRegistrar?taskRegistrar)?{
????????//設(shè)定一個(gè)長(zhǎng)度10的定時(shí)任務(wù)線程池
????????taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
????}
}
2、通過(guò)配置開(kāi)啟
Spring Boot quartz 已經(jīng)提供了一個(gè)配置用來(lái)配置線程池的大小,如下;
spring.task.scheduling.pool.size=10
只需要在配置文件中添加如上的配置即可生效!
3、結(jié)合@Async
@Async這個(gè)注解都用過(guò),用來(lái)開(kāi)啟異步任務(wù)的,使用@Async這個(gè)注解之前一定是要先配置線程池的,配置如下:
????@Bean
????public?ThreadPoolTaskExecutor?taskExecutor()?{
????????ThreadPoolTaskExecutor?poolTaskExecutor?=?new?ThreadPoolTaskExecutor();
????????poolTaskExecutor.setCorePoolSize(4);
????????poolTaskExecutor.setMaxPoolSize(6);
????????//?設(shè)置線程活躍時(shí)間(秒)
????????poolTaskExecutor.setKeepAliveSeconds(120);
????????//?設(shè)置隊(duì)列容量
????????poolTaskExecutor.setQueueCapacity(40);
????????poolTaskExecutor.setRejectedExecutionHandler(new?ThreadPoolExecutor.CallerRunsPolicy());
????????//?等待所有任務(wù)結(jié)束后再關(guān)閉線程池
????????poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
????????return?poolTaskExecutor;
????}
然后在@Scheduled方法上標(biāo)注@Async這個(gè)注解即可實(shí)現(xiàn)多線程定時(shí)任務(wù),代碼如下:
?@Async
????@Scheduled(cron?=?"0/2?*?*?*?*???")
????public?void?test2()?{
????????System.out.println("..................執(zhí)行test2.................");
????}
總結(jié)
本篇文章介紹了Spring Boot 中 實(shí)現(xiàn)多線程定時(shí)任務(wù)的三種方案,你喜歡哪一種?
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過(guò)內(nèi)容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標(biāo)”,這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。
點(diǎn)“在看”支持一下吧??!

