摘要:前言在使用整合定時任務(wù),發(fā)現(xiàn)當(dāng)某個定時任務(wù)執(zhí)行出現(xiàn)執(zhí)行時間過長的情況時會阻塞其他定時任務(wù)的執(zhí)行。問題定位后續(xù)通過翻查的文檔以及打印日志輸出當(dāng)前線程信息得知問題是由于默認(rèn)使用只要個線程處理定時任務(wù)。問題復(fù)盤需要注意示例的版本為。
前言
在使用Springboot整合定時任務(wù),發(fā)現(xiàn)當(dāng)某個定時任務(wù)執(zhí)行出現(xiàn)執(zhí)行時間過長的情況時會阻塞其他定時任務(wù)的執(zhí)行。
問題定位后續(xù)通過翻查Springboot的文檔以及打印日志(輸出當(dāng)前線程信息)得知問題是由于Springboot默認(rèn)使用只要1個線程處理定時任務(wù)。
問題復(fù)盤需要注意示例的Springboot版本為2.1.3.RELEASE。
關(guān)鍵pom文件配置定時任務(wù)...省略非關(guān)鍵配置 org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** * 定時任務(wù) * @author RJH * create at 2019-03-29 */ @Component public class SimpleTask { private static Logger logger= LoggerFactory.getLogger(SimpleTask.class); /** * 執(zhí)行會超時的任務(wù),定時任務(wù)間隔為5000ms(等價于5s) */ @Scheduled(fixedRate = 5000) public void overtimeTask(){ try { logger.info("current run by overtimeTask"); //休眠時間為執(zhí)行間隔的2倍 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 正常的定時任務(wù) */ @Scheduled(fixedRate = 5000) public void simpleTask(){ logger.info("current run by simpleTask"); } }啟動類
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class TaskDemoApplication { public static void main(String[] args) { SpringApplication.run(TaskDemoApplication.class, args); } }運行結(jié)果
...省略非關(guān)鍵信息 2019-03-29 21:22:38.410 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:38.413 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:22:48.413 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:48.414 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:22:58.418 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:22:58.418 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:23:08.424 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:23:08.424 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask 2019-03-29 21:23:18.425 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by simpleTask 2019-03-29 21:23:18.426 INFO 59731 --- [ scheduling-1] com.rjh.task.SimpleTask : current run by overtimeTask ...結(jié)果分析
由運行結(jié)果可以看出:
每次定時任務(wù)的運行都是由scheduling-1這個線程處理
正常運行的simpleTask被overtimeTask阻塞導(dǎo)致了運行間隔變成了10秒
后面通過查閱Springboot的文檔也得知了定時任務(wù)默認(rèn)最大運行線程數(shù)為1。
解決方案由于使用的Springboot版本為2.1.3.RELEASE,所以有兩種方法解決這個問題
使用Springboot配置在配置文件中可以配置定時任務(wù)可用的線程數(shù):
## 配置可用線程數(shù)為10 spring.task.scheduling.pool.size=10自定義定時任務(wù)的線程池
使用自定義的線程池代替默認(rèn)的線程池
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; /** * 定時任務(wù)配置類 * @author RJH * create at 2019-03-29 */ @Configuration public class ScheduleConfig { /** * 此處方法名為Bean的名字,方法名無需固定 * 因為是按TaskScheduler接口自動注入 * @return */ @Bean public TaskScheduler taskScheduler(){ // Spring提供的定時任務(wù)線程池類 ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler(); //設(shè)定最大可用的線程數(shù)目 taskScheduler.setPoolSize(10); return taskScheduler; } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74002.html
摘要:也是自帶的一個基于線程池設(shè)計的定時任務(wù)類。其每個調(diào)度任務(wù)都會分配到線程池中的一個線程執(zhí)行,所以其任務(wù)是并發(fā)執(zhí)行的,互不影響。 原創(chuàng)不易,如需轉(zhuǎn)載,請注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責(zé)任?。。?一、在JAVA開發(fā)領(lǐng)域,目前可以通過以下幾種方式進行定時任務(wù) 1、單機部署模式 Timer:jdk中...
摘要:定時任務(wù)間隔時間方式執(zhí)行一次定時任務(wù)線程休眠規(guī)定時間類類允許調(diào)度一個任務(wù)。引入依賴配置測試執(zhí)行一次定時任務(wù)使用注解是為定時任務(wù)而生的一個注解,查看注解的源碼表達式接收一個。 本文旨在用通俗的語言講述枯燥的知識 定時任務(wù)作為一種系統(tǒng)調(diào)度工具,在一些需要有定時作業(yè)的系統(tǒng)中應(yīng)用廣泛,如每逢某個時間點統(tǒng)計數(shù)據(jù)、在將來某個時刻執(zhí)行某些動作...定時任務(wù)在主流開發(fā)語言均提供相應(yīng)的API供開發(fā)者調(diào)用...
摘要:構(gòu)建工程創(chuàng)建一個工程,在它的程序入口加上開啟調(diào)度任務(wù)。創(chuàng)建定時任務(wù)創(chuàng)建一個定時任務(wù),每過在控制臺打印當(dāng)前時間。通過在方法上加注解,表明該方法是一個調(diào)度任務(wù)。 這篇文章將介紹怎么通過spring去做調(diào)度任務(wù)。 構(gòu)建工程 創(chuàng)建一個Springboot工程,在它的程序入口加上@EnableScheduling,開啟調(diào)度任務(wù)。 @SpringBootApplication @EnableSch...
摘要:而我這里定時任務(wù)的觸發(fā)是要通過接口的方式來觸發(fā),所以只用實現(xiàn)以下的調(diào)度器即可。我這里簡單說下任務(wù)的調(diào)度器,具體的任務(wù)類,觸發(fā)器,任務(wù)什么時候執(zhí)行是由它決定的。遇到的坑解決方式這個是因為不兼容的問題,所以使用是不會出現(xiàn)這個錯誤的。 實現(xiàn)定時任務(wù)的幾種方式: 1.使用linux的crontab 優(yōu)點: 1.使用方式很簡單,只要在crontab中寫好 2.隨時可以修改,不需要...
閱讀 1279·2021-11-23 09:51
閱讀 1637·2021-11-16 11:45
閱讀 4073·2021-10-09 09:43
閱讀 2698·2021-07-22 16:47
閱讀 958·2019-08-27 10:55
閱讀 3461·2019-08-26 17:40
閱讀 3100·2019-08-26 11:39
閱讀 3238·2019-08-23 18:39