@Schedule?如何解決定時(shí)任務(wù)推遲執(zhí)行
前言
SpringBoot 實(shí)現(xiàn)定時(shí)任務(wù)很簡(jiǎn)單,只需要使用**@Scheduled**注解即可,但是該注解是實(shí)現(xiàn)的定時(shí)任務(wù)默認(rèn)是單線程的,也就意味著多個(gè)定時(shí)任務(wù)執(zhí)行時(shí)就可能導(dǎo)致線程堵塞,延緩定時(shí)任務(wù)的執(zhí)行。
下面就一步一步來(lái)解決這個(gè)問(wèn)題。
一、@Scheduled
1、代碼
// 啟用定時(shí)任務(wù) @EnableScheduling @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
@Component public class Task { Logger logger = LoggerFactory.getLogger(Task.class); // 每五秒執(zhí)行一次 @Scheduled(cron = "0/5 * * * * ?") public void taskTestA() throws InterruptedException { logger.info("A:"); TimeUnit.SECONDS.sleep(20); } // 每十秒執(zhí)行一次 @Scheduled(cron = "0/10 * * * * ?") public void taskTestB() { logger.info("B:"); } }
2、結(jié)果
由圖可知,首先這兩個(gè)定時(shí)任務(wù)都是單線程的,但是當(dāng)定時(shí)A執(zhí)行了一次后,由于定時(shí)A中有個(gè)休眠20秒,然后執(zhí)行定時(shí)任務(wù)B,所以線程A第二次執(zhí)行在25秒后才執(zhí)行,這就是由于@Scheduled定時(shí)任務(wù)是單線程,造成的線程堵塞,導(dǎo)致定時(shí)任務(wù)推遲執(zhí)行。
二、@Scheduled + 配置線程池
1、代碼
和前面@Scheduled 相比,僅僅增加了配置線程池
// 若不設(shè)置默認(rèn)為單線程,這里設(shè)置使用線程池,大小為4 spring: task: scheduling: pool: size: 4
2、結(jié)果
由圖可知,增加了線程池,這樣使得定時(shí)任務(wù)A和B在不同的線程進(jìn)行執(zhí)行,但是定時(shí)任務(wù)A的第二次執(zhí)行,依舊是在25秒后執(zhí)行,由此可知這種方式其實(shí)解決的是不同定時(shí)任務(wù)之間的進(jìn)程堵塞。
三、@Scheduled + @Async
1、代碼
和前面相比,僅僅增加了配置
// 啟用異步,動(dòng)態(tài)創(chuàng)建線程 @EnableAsync @EnableScheduling @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
@Component public class Task { Logger logger = LoggerFactory.getLogger(Task.class); // 異步,動(dòng)態(tài)創(chuàng)建線程 @Async @Scheduled(cron = "0/5 * * * * ?") public void taskTestA() throws InterruptedException { logger.info("A:"); TimeUnit.SECONDS.sleep(20); } // 異步,動(dòng)態(tài)創(chuàng)建線程 @Async @Scheduled(cron = "0/10 * * * * ?") public void taskTestB() { logger.info("B:"); } }
2、結(jié)果
由圖可知,啟用了異步,使用了spring 默認(rèn)的線程池,動(dòng)態(tài)創(chuàng)建線程,這樣使得定時(shí)任務(wù)A和B在不同的線程進(jìn)行執(zhí)行,同時(shí)任務(wù)A的多次運(yùn)行也是異步執(zhí)行,這樣就能確保所有定時(shí)任務(wù)不會(huì)延遲執(zhí)行!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
idea2020安裝MybatisCodeHelper插件的圖文教程
這篇文章主要介紹了idea2020安裝MybatisCodeHelper插件的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Mybatis中resultMap標(biāo)簽和sql標(biāo)簽的設(shè)置方式
這篇文章主要介紹了Mybatis中resultMap標(biāo)簽和sql標(biāo)簽的設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01Java?超詳細(xì)講解類的定義方式和對(duì)象的實(shí)例化
Java是一門純面向?qū)ο蟮恼Z(yǔ)言(Object?Oriented?Program,繼承OOP),在面對(duì)對(duì)象的世界里面,一切皆為對(duì)象。面向?qū)ο笫墙鉀Q問(wèn)題的一種思想,主要依靠對(duì)象之間的交互完成一件事情2022-03-03說(shuō)說(shuō)在Spring中如何引用外部屬性文件的方法
這篇文章主要介紹了說(shuō)說(shuō)在Spring中如何引用外部屬性文件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05mybatis實(shí)現(xiàn)獲取入?yún)⑹荓ist和Map的取值
這篇文章主要介紹了mybatis實(shí)現(xiàn)獲取入?yún)⑹荓ist和Map的取值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Java設(shè)計(jì)模式之抽象工廠模式簡(jiǎn)析
這篇文章主要介紹了Java設(shè)計(jì)模式之抽象工廠模式簡(jiǎn)析, 抽象工廠模式是工廠方法模式的升級(jí)版本,他用來(lái)創(chuàng)建一組相關(guān)或者相互依賴的對(duì)象,他與工廠方法模式的區(qū)別就在于,工廠方法模式針對(duì)的是一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),需要的朋友可以參考下2023-12-12Spring Cloud分布式定時(shí)器之ShedLock的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud分布式定時(shí)器之ShedLock的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03java中ExecutorService創(chuàng)建方法總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于java中ExecutorService創(chuàng)建方法總結(jié),有興趣的朋友們可以參考下。2021-01-01基于Properties類操作.properties配置文件方法總結(jié)
這篇文章主要介紹了Properties類操作.properties配置文件方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09