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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...