【Spring】Spring的定時任務註解@Scheduled原來如此簡單

来源:https://www.cnblogs.com/larrydpk/archive/2019/11/19/11893942.html
-Advertisement-
Play Games

1 簡介 定時任務的實現非常多,JDK的 Timer 、Spring提供的輕量級的 Scheduled Task 、 QuartZ 和 Linux Cron 等,還有一些分散式的任務調度框架。本文主要介紹 Scheduled Task 的使用。 2 方便的4種方式 註解 只能用於滿足下麵兩個條件的方 ...


1 簡介

定時任務的實現非常多,JDK的Timer、Spring提供的輕量級的Scheduled TaskQuartZLinux Cron等,還有一些分散式的任務調度框架。本文主要介紹Scheduled Task的使用。

2 方便的4種方式

註解@Scheduled只能用於滿足下麵兩個條件的方法上:

(1)沒有返回類型,或者說返回類型為void

(2)沒有參數;

開啟Spring的Scheduler非常簡單,一個註解@EnableScheduling即可:

@Configuration
@EnableScheduling
public class SchedulingConfig {
}

如果是Springboot應用,則直接在啟動類上面加上@EnableScheduling就可以使用了。

2.1 固定延遲fixedDelay

代表下一個任務的開始與上一個任務的結束間隔總是固定的時長,而且總是會等上一個任務完成了,才會開啟下一個任務。如果需求是有這樣依賴要求的,使用這種模式是非常合適的。代碼如下:

@Scheduled(fixedDelay = 1000)
public void fixedDelay() {
  log.info("fixedDelay");
}

參數為1000,代表固定延遲為1000毫秒,即1秒鐘,所以輸出為:

2019-11-19 21:02:43,977 scheduling-1:fixedDelay 
2019-11-19 21:02:44,981 scheduling-1:fixedDelay 
2019-11-19 21:02:45,983 scheduling-1:fixedDelay 
2019-11-19 21:02:46,984 scheduling-1:fixedDelay 

2.2 固定頻率fixedRate

2.2.1 正常情況

定頻任務的特性是任務的執行的時間間隔總是一樣的。比如每1小時執行一次,就是任務執行開始的時間點的時間間隔為1小時。代碼如下:

@Scheduled(fixedRate = 2000)
public void fixedRate() {
  log.info("fixedRate");
}

參數為2000,則每2秒執行一次,輸出為:

2019-11-19 21:38:45,073 scheduling-1:fixedRate 
2019-11-19 21:38:47,076 scheduling-1:fixedRate 
2019-11-19 21:38:49,073 scheduling-1:fixedRate 
2019-11-19 21:38:51,075 scheduling-1:fixedRate 

2.2.2 預設單線程

需要註意的是它預設是單線程的,不會並行執行。即使是固定頻率,但下一次的任務也必須等到上一次任務執行完畢才會開始。下麵這個例子能很好說明:

@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
  log.info("fixedRateLongTimeTask");
  Thread.sleep(3000);
}

由於任務需要執行3秒才能完成,即使fixedRate設置為1秒,並不能每一秒執行一次,輸出如下:

2019-11-19 21:46:00,108 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:03,113 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:06,113 scheduling-1:fixedRateLongTimeTask 
2019-11-19 21:46:09,117 scheduling-1:fixedRateLongTimeTask 

每3次輸出一次。

2.2.3 註解@Async來幫你

上述問題有辦法解決嗎?答案是肯定的,而且非常簡單。只需要加一個註解@Async就可以使任務能非同步多線程地執行了,代碼如下:

@Async
@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
  log.info("fixedRateLongTimeTask");
  Thread.sleep(3000);
}

通過日誌可以看出是每秒執行一次的,即使前面的任務還沒有完成。而且線程名不一樣,通過多線程來執行,輸出結果為:

2019-11-19 21:54:22,261 task-5:fixedRateLongTimeTask 
2019-11-19 21:54:23,257 task-6:fixedRateLongTimeTask 
2019-11-19 21:54:24,257 task-4:fixedRateLongTimeTask 
2019-11-19 21:54:25,257 task-8:fixedRateLongTimeTask 
2019-11-19 21:54:26,259 task-1:fixedRateLongTimeTask 
2019-11-19 21:54:27,262 task-2:fixedRateLongTimeTask 
2019-11-19 21:54:28,260 task-3:fixedRateLongTimeTask 

註意:需要指出的是,需要像@EnableScheduling一樣,需要添加配置註解@EnableAsync來打開這個功能開關。另外,如果任務執行時間很長,例如1分鐘,情況又不一樣。以後再詳細介紹@Async的使用吧。

2.3 初始延遲initialDelay

初始延遲是用initialDelay來指定的,它可以延遲第一次任務執行的時間。如下例子的參數為30秒,則在啟動30秒後,才開始執行第一次。可以減輕項目啟動的負擔,也可以為任務執行前準備數據。

@Scheduled(fixedDelay = 1000, initialDelay = 30*1000)
public void fixedDelayWithIntialDelay() {
  log.info("fixedDelayWithIntialDelay");
}

輸出如下:

2019-11-19 22:10:02,092 main:Tomcat started on port(s): 443 (http) with context path '' 
2019-11-19 22:10:02,095 main:Started DemoApplication in 1.272 seconds (JVM running for 1.767) 
2019-11-19 22:10:32,063 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:33,067 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:34,069 scheduling-1:fixedDelayWithIntialDelay 
2019-11-19 22:10:35,069 scheduling-1:fixedDelayWithIntialDelay

可以看出,在項目啟動後30秒左右,才開始執行任務。

2.4 Cron表達式

上述提供的功能並不能滿足定時任務調度的所有需求,比如需要每個月1號發送簡訊,每周六做數據分析等。這裡Cron表達式就派上用場了。

下麵的例子表示每當秒數為06的時候就執行。代碼如下:

@Scheduled(cron = "6 * * ? * *")
public void cron() {
  log.info("cron");
}

結果如下:

2019-11-19 22:20:06,003 scheduling-1:cron 
2019-11-19 22:21:06,004 scheduling-1:cron 
2019-11-19 22:22:06,002 scheduling-1:cron 

Cron表達式功能非常強大,網上資料很豐富,這裡不展開講了。

3 參數配置化

之前的例子都將參數寫死在代碼上了,如果需要更靈活,其實可以用參數來配置。這樣需要修改參數的時候,不用修改代碼、編譯打包再部署了,直接修改配置文件即可。

代碼如下:

@Scheduled(cron = "${pkslow.cron}")
public void cronWithConfig() {
  log.info("cronWithConfig");
}

在application.properties配置如下:

pkslow.cron=* * * ? * *

代碼1秒執行一次。

4 如果她突然消失了

由於Spring的Scheduler預設是單線程的,這樣會存在一個問題,如果某個任務執行卡住了,那就無法繼續往下執行了。在日誌上表現就是突然消失了。這種情況出現的概率還是不小的,如操作資料庫死鎖了,http請求timeout為無限等待,還有其它原因的死鎖等。

當遇到這種情況,應通過命令jstack pid > pid.ThreadDump.txt獲取當前線程情況,然後分析是否真的是卡住了,卡在了哪個環節,然後再分析具體代碼。通過設置超時或重試等方法來解決。

5 結論

本文主要介紹了Spring的定時任務註解@Scheduled的使用,講述了多種方式的使用和配置。它非常方便簡潔,對於簡單的定時任務足以應對了。


歡迎關註公眾號<南瓜慢說>,將持續為你更新...

file

多讀書,多分享;多寫作,多整理。


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

-Advertisement-
Play Games
更多相關文章
  • JS數據類型分為簡單數據類型(基本數據類型)和複雜數據類型(引用數據類型)。 基本數據類型:Undefined、Null、Boolean、Number、String、Symbol。 引用數據類型:Object。 可以通過typeof操作符判斷以上7種數據類型,語法:typeof 變數,返回值如下: ...
  • 之前在工作中,有位同事問過我一個問題,JS如何實現點擊複製功能。給他解決後現在來總結歸納一下,順便做個筆記。 PS:此乃本人第一篇博客(跟著同事大佬學習),涉及知識尚淺,如有任何意見和建議請告知於我。下麵開始正文: <!DOCTYPE html> <html> <head> <meta charse ...
  • 1.html <el-table-column prop="taxes" :render-header="renderHeader" width="180"> <template slot-scope="scope">{{scope.row.taxes}}</template> </el-table ...
  • Zongsoft.Data 是一個類 GraphQL 風格的 ORM(Object/Relational Mapping) 數據訪問框架。很高興我們的 ORM 數據訪問框架在歷經兩個 SaaS 產品的應用之後,今天正式宣佈對外推廣! ...
  • 概念 “4+1”視圖,是指從5個不同視角來描述軟體體繫結構。 “4+1”分別指: 1. 邏輯視圖 2. 過程視圖 3. 物理視圖 4. 開發視圖 5. 場景/用例 視圖 邏輯架構的描述可以圍繞前四個視圖進行組織,然後結合用例或場景進行說明,形成第五個視圖。 每個視圖只關心系統的一個側面,5個視圖結合 ...
  • 系統分析師 軟體水平考試(高級) 理論 系統規劃 前言 系統規劃是什麼東東呢? 通俗點說,就是為了實現企業的戰略目標,分析企業現狀(技術外部)與系統狀況(技術內部),從而提出新的技術要求,對現有系統進行規劃設計等變化。 1. 目標是實現企業戰略目標; 2. 分析企業現狀(瞭解情況了,才能下手唄。站在 ...
  • 一、UDP編程 1.客戶端Client:發起訪問的一方。 2.伺服器端 3.server段編程 (1)建立socket,socket是負責具體通信的一個實例 (2)綁定,為創建的socket指派固定的埠和IP地址 (3)接受對方發送內容 (4)給對方發送反饋,此步驟為非必須步驟 4.Client端 ...
  • 你好,我是彤哥,本篇是netty系列的第四篇。 歡迎來我的公從號 彤哥讀源碼 系統地學習 源碼&架構 的知識。 簡介 上一章我們一起學習了Java中的BIO/NIO/AIO的故事,本章將帶著大家一起使用純純的NIO實現一個越聊越上癮的“群聊系統”。 業務邏輯分析 首先,我們先來分析一下群聊的功能點: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...