您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“定時任務@Scheduled沒有準時執行怎么解決”,內容詳細,步驟清晰,細節處理妥當,希望這篇“定時任務@Scheduled沒有準時執行怎么解決”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
項目中用到了定時任務往前端推送數據,間隔2秒 @Scheduled(cron = "0/2 * * * * ? "),測試發現,每次任務執行并不是2秒,而是1-5秒之間。
執行時間:::::Wed Nov 30 16:20:19 CST 2022
執行時間:::::Wed Nov 30 16:20:20 CST 2022
執行時間:::::Wed Nov 30 16:20:24 CST 2022
執行時間:::::Wed Nov 30 16:20:29 CST 2022
了解發現,如果程序中沒有指定線程池的配置,也就是Spring的Scheduled的默認線程池配置,其線程池的線程數默認為1,也就是說默認情況下,Spring用來處理定時任務的線程只有一個。
如果有定時的處理時間占用時間比較長,那么就會導致下一個定時任務,即使到達了配置的定時時間,也不會立即執行,而是等到前面一個任務處理完成了,才會進行處理。
而項目中還有數個定時任務。
是初始一個定時任務執行線程池
@Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { Method[] methods = BatchProperties.Job.class.getMethods(); int defaultPoolSize = 10; int corePoolSize = 0; if (methods != null && methods.length > 0) { for (Method method : methods) { Scheduled annotation = method.getAnnotation(Scheduled.class); if (annotation != null) { corePoolSize++; } } if (defaultPoolSize > corePoolSize) corePoolSize = defaultPoolSize; } taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize)); } }
再次測試,跟設置的間隔時間2秒一致。
執行時間:::::Wed Nov 30 16:48:32 CST 2022
執行時間:::::Wed Nov 30 16:48:34 CST 2022
執行時間:::::Wed Nov 30 16:48:36 CST 2022
執行時間:::::Wed Nov 30 16:48:38 CST 2022
啟動類添加注解
@EnableScheduling // 開啟定時任務
cron 表達式
/** * cron 表達式 * 每2秒執行一次 * @throws InterruptedException */ @Scheduled(cron = "0/2 * * * * *") public void test() throws InterruptedException { // 經過測試,使用cron表達式,定時任務第二次會等待第一次執行完畢再開始! Thread.sleep(5000L); log.info("定時任務測試cron:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); }
fixedDelay
/** * fixedDelay: * 第一次執行完畢才會執行第二次,時間間隔變為了7秒 * @throws InterruptedException */ @Scheduled(fixedDelay = 2000L) public void test2() throws InterruptedException { Thread.sleep(5000L); log.info("定時任務測試fixedDelay:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); }
fixedRate
/** * fixedRate: * 每隔2秒就會執行, 但是因為單線程,所以在5秒后會輸出,間隔就是5秒 * @throws InterruptedException */ @Scheduled(fixedRate = 2000L) public void test3() throws InterruptedException { Thread.sleep(5000L); log.info("定時任務測試fixedRate:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); }
如果是一起執行這三個定時任務,那么會一個一個的來, 因為只有一個線程.
/** * * @author GMaya */ @Configuration @EnableAsync public class ScheduleConfig { @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); taskScheduler.setPoolSize(50); // 設置線程池大小 return taskScheduler; } }
如果只是加這一個配置類, 確實是使用了多線程, 每個定時任務都互相不影響.
但是一個線程第一次阻塞了,第二次就不行了,所以在定時任務上再加
@Async
就是說你這次失敗了, 不要影響我下次的運行
讀到這里,這篇“定時任務@Scheduled沒有準時執行怎么解決”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。