Spring6.x對調度和非同步執行的註解支持

来源:https://www.cnblogs.com/JavaEdge/archive/2023/11/23/17851902.html
-Advertisement-
Play Games

Spring為任務調度和非同步方法執行提供註解支持。 1 啟用Scheduling註解 要啟用 @Scheduled 和 @Async ,在 @Configuration 類(或者在啟動類)添加 @EnableScheduling 和 @EnableAsync,如下: @Configuration @ ...


Spring為任務調度和非同步方法執行提供註解支持。

1 啟用Scheduling註解

要啟用 @Scheduled@Async ,在 @Configuration 類(或者在啟動類)添加 @EnableScheduling@EnableAsync,如下:

@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {

}
@SpringBootApplication(exclude = {
		DataSourceAutoConfiguration.class,
})
@EnableScheduling
public class RoadSyncApplication {

	public static void main(String[] args) {
		SpringApplication.run(RoadSyncApplication.class, args);
	}
}

你可以為你的應用程式選擇相關的註解。例如,如果你只需要支持 @Scheduled,可以省略 @EnableAsync。對於更細粒度的控制,你還可以分別實現 SchedulingConfigurer 介面和 AsyncConfigurer 介面。有關完整詳細信息,請參閱 SchedulingConfigurerAsyncConfigurer javadoc。

預設處理 @Async 註解的建議模式是 proxy,它僅允許通過代理攔截調用。使用這種方式無法攔截同一類中的本地調用。 對於更高級的攔截模式,請考慮切換到 aspectj 模式與編譯時織入或載入時織入結合使用。

2 @Scheduled 註解

可將 @Scheduled 註解以及觸發元數據添加到方法中。

2.1 fixedDelay

如下方法每5000ms執行一次,採用固定延遲,即周期從每次先前調用的【完成時間】開始測量。

@Scheduled(fixedDelay = 5000)  
public void doSomething() {
	// 定期運行的內容  
}

預設,固定延遲、固定速率和初始延遲的值將使用ms作時間單位。如想用不同時間單位,如s或min,可在 @Scheduled 配置 timeUnit 屬性:

@Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
public void doSomething() {
}

2.2 fixedRate

如需固定速率執行,使用 fixedRate 屬性。下麵的方法每五秒(從每次【調用的開始時間】間隔測量)執行一次:

@Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)  
public void doSomething() {

}

固定延遲、固定速率的任務,可通過指示等待的時間量來指定初始延遲,然後再執行方法的第一次調用:

@Scheduled(initialDelay=1000, fixedRate=5000)  
public void doSomething() {
	// 定期運行的內容
}

2.3 一次性任務

可只指定通過指示等待執行方法的時間量的初始延遲:

@Scheduled(initialDelay=1000)
public void doSomething() {
	// 只運行一次
}

若簡單的定期計劃不夠表達力,可用 cron 表達式:

@Scheduled(cron="*/5 * * * * MON-FRI")  
public void doSomething() {
	// 僅在工作日運行的內容 
}

還可使用 zone 屬性指定解析 cron 表達式的時區。

要計劃的方法須有 void 返回值,且不接受任何參數。如果方法需要與應用程式上下文中的其他對象交互,那麼這些對象通常已經通過依賴註入。

@Scheduled 是可重覆註解。如在同一方法上找到幾個 scheduled 聲明,每個聲明都將獨立處理,為每個聲明觸發單獨的觸發器。因此,這樣的共定位計劃可並行重疊並立即連續執行多次。請確保你指定的 cron 表達式等不會意外重疊。

Spring Framework 4.3 開始,支持任何範圍的 bean 上的 @Scheduled 方法。確保在運行時不初始化同一 @Scheduled 註解類的多個實例,除非你確實希望調度回調到每個這樣的實例。

確保不要在使用 @Scheduled 註解並作為常規 Spring bean 註冊到容器中的 bean 類上使用 @Configurable。否則,你將獲得雙重初始化(一次通過容器,一次通過 @Configurable 方面),其結果是每個 @Scheduled 方法被調用兩次。

FAQ

問題

生產用@Scheduled註解寫定時任務,5min執行一次:

@Scheduled(cron = "0 0/5 * * * ?")
public void MyTimerJobSchedule() throws Exception {
  //省略具體業務邏輯
  System.out.println("五分鐘執行一次");
}

過幾天,領導通知說有問題,一查日誌,發現是定時任務問題。本來應該是5min跑一次,結果日誌發現,每天0點-3點正常,3-10點沒執行;一直到10-11點之間才繼續跑。

原因

發現可能是定時任務單線程模式導致任務阻塞。

繼續分析日誌,發現該定時任務的線程號是[Scheduling-1],除了執行自身的任務,還列印了其它定時任務的輸出語句。

每天3點前,[Scheduling-1]線程在執行本人寫的5min一次的定時任務,3點後,[Scheduling-1]線程會執行另一個比較耗時的定時任務,直到10點後,[Scheduling-1]線程才重新執行5min一次的定時任務。

看來,確實是由於@Scheduled定時任務預設使用單線程模式導致:一旦有一個定時任務比較耗時,就會影響到其它定時任務按時執行。

解決方法

在定時任務加@Async註解,併在啟動類增加@EnableAsync註解,使用多線程模式執行定時任務。

備註:
參考網址:https://blog.csdn.net/LYM0721/article/details/89499588

參考網址中有第二種解決方法,但是已說明不太好用,因此只用第一種解決方法就夠了。

本文由博客一文多發平臺 OpenWrite 發佈!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • React實現視覺差效果緩動輪播 效果如下(圖片幀率低看起來有點卡頓,看個大概就行): 分享一下思路: 1.正常引入一個輪播組件(站在巨人肩膀省時省力),去除指示點、引導箭頭等不需要的元素,有些組件支持配置,不支持就手動覆蓋CSS樣式了 2.找到組件中用於顯示展示當前圖片的類名 3.添加transf ...
  • Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境,使用了一個事件驅動、非阻塞式 I/O 模型,讓 JavaScript 運行在服務端的開發平臺。 ...
  • 一、Vue3結構分析 1、Vue2與Vue3的對比 對TypeScript支持不友好(所有屬性都放在了this對象上,難以推倒組件的數據類型) 大量的API掛載在Vue對象的原型上,難以實現TreeShaking。 架構層面對跨平臺dom渲染開發支持不友好,vue3允許自定義渲染器,擴展能力強。 C ...
  • UDP 分片 與 丟包,UDP 真的比 TCP 高效嗎?UDP(用戶數據報協議)和TCP(傳輸控制協議)在很多方面都有顯著的區別。總體來說,TCP更適合需要可靠傳輸的應用,例如網頁瀏覽、電子郵件等,而UDP則更適合對速度有高要求,但對數據完整性要求較低的應用,例如實時視頻流或游戲。在多數網路環境下, ...
  • 十五、聯合體(union) 1、union語法 ​ 聯合體和結構體都是自定義數據類型 ,通過union可以創建一個聯合體,union中的成員變數共用記憶體(即記憶體中有重疊的部分),因此union的數據類型大小由其最大的成員變數決定。 //聯合體union語法 union 聯合體名稱 { 變數類型 變數 ...
  • 前言 位元組跳動如果上市,那麼鐘老闆將成為我國第一個世界首富 趁著現在還沒上市,咱們提前學習一下用Python分析股票歷史數據,抱住粗大腿坐等起飛~ 好了話不多說,我們直接開始正文 準備工作 環境使用 Python 3.10 解釋器 Pycharm 編輯器 模塊使用 requests —> 數據請求模 ...
  • 十四、指針和引用(四) 1、字元處理(字元串) 1)字元串 ​ 日常生活中,單個字元無法滿足我們的需求,比如一個單詞hello要由五個字元組成,名字張三要由兩個中文字元來組成,我們把這種連續的字元稱為字元串,字元串在記憶體中的表現就是連續的字元。比如hello在記憶體中是這樣子的。 ​ 註:字元在記憶體中 ...
  • 現一個 Java 21 中有意思的東西! 在java.Lang.Character類中增加了用於確定字元是否為 Emoji 表情符號的 API,主要包含下麵六個新的靜態方法: public static boolean isEmoji(int codePoint) { return Characte ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...