SpringBoot定時任務 - Timer實現方式

定時任務在實際開發中有著廣泛的用途,本文主要幫助你構建定時任務的知識體系,同時展示Timer 的schedule和scheduleAtFixedRate例子;后續的文章中我們將逐一介紹其它常見的與SpringBoot的集成。

知識準備

需要對定時任務的使用場景和常見的實現方式。

什么樣的場景會使用定時任務?

比如每天/每周/每月生成日志匯總,定時發送推送信息,定時生成數據表格等

定時任務有哪些實現方式?

首先你需要構建如下實現定時任務的知識體系。在后續的文章中我們將逐一介紹在SpringBoot下的集成。

  • 定時任務基礎
    • Cron表達式
    • Linux定時任務工具crontb
  • JDK內置
    • Timer
    • ScheduleExecutorService
  • Netty
    • HashedWheelTimer
  • Spring
    • Spring自帶Schedule
    • Spring集成Quartz
  • 分布式集群
    • Quartz持久化JDBC方式
    • Elastic-job
    • xxl-job

Timer實現案例

Timer 的schedule和scheduleAtFixedRate例子如下。

schedule延遲任務

執行定時任務,延遲1秒開始執行。

@SneakyThrows
public static void timer() {// start timerTimer timer = new Timer();timer.schedule(new TimerTask() {public void run() {log.info("timer-task @{}", LocalDateTime.now());}}, 1000);// waiting to process(sleep to mock)Thread.sleep(3000);// stop timertimer.cancel();
}

輸出

10:05:47.440 [Timer-0] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-task @2021-10-01T20:05:47.436

schedule周期任務

延遲0.5秒開始執行,每秒執行一次, 10秒后停止。

@SneakyThrows
public static void timerPeriod() {// start timerTimer timer = new Timer();timer.schedule(new TimerTask() {@SneakyThrowspublic void run() {log.info("timer-period-task @{}", LocalDateTime.now());Thread.sleep(100); // 可以設置的執行時間, 來測試當執行時間大于執行周期時任務執行的變化 }}, 500, 1000);// waiting to process(sleep to mock)Thread.sleep(10000);// stop timertimer.cancel();
}

輸出

10:05:49.781 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:49.781
10:05:50.781 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:50.781
10:05:51.781 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:51.781
10:05:52.781 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:52.781
10:05:53.782 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:53.782
10:05:54.783 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:54.783
10:05:55.783 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:55.783
10:05:56.784 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:56.784
10:05:57.785 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:57.785
10:05:58.786 [Timer-1] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-period-task @2021-10-01T10:05:58.786

scheduleAtFixedRate

延遲0.5秒開始執行,每秒執行一次, 10秒后停止。

同時測試某次任務執行時間大于周期時間的變化。

@SneakyThrows
public static void timerFixedRate() {// start timerTimer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {int count = 0;@SneakyThrowspublic void run() {if (count++==2) {Thread.sleep(5000); // 某一次執行時間超過了period(執行周期)}log.info("timer-fixedRate-task @{}", LocalDateTime.now());}}, 500, 1000);// waiting to process(sleep to mock)Thread.sleep(10000);// stop timertimer.cancel();
}

輸出

10:05:59.781 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:05:59.781
10:06:00.782 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:00.782
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:06.783 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:06.783
10:06:07.781 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:07.781
10:06:08.781 [Timer-2] INFO tech.aizer.springboot.schedule.timer.timertest.TimerTester - timer-fixedRate-task @2021-10-01T10:06:08.781

(你會發現周期執行1秒中執行一次,但是某次執行了5秒,這時候,后續的任務會加快執行進度,一次性就執行了,執行的時間都是10:06:06.783, 所以scheduleAtFixedRate最大的特點是保證了總時間段內的執行次數

進一步理解

我們再通過一些問題來幫助你更深入理解Timer實現方式。

schedule 和 scheduleAtFixedRate 有何區別?

  • schedule:每次執行完當前任務后,然后間隔一個period的時間再執行下一個任務; 當某個任務執行周期大于時間間隔時,依然按照間隔時間執行下個任務,即它保證了任務之間執行的間隔
  • scheduleAtFixedRate:每次執行時間為上一次任務開始起向后推一個period間隔,也就是說下次執行時間相對于上一次任務開始的時間點;按照上述的例子,它保證了總時間段內的任務的執行次數

為什么幾乎很少使用Timer這種方式?

Timer底層是使用一個單線來實現多個Timer任務處理的,所有任務都是由同一個線程來調度,所有任務都是串行執行,意味著同一時間只能有一個任務得到執行,而前一個任務的延遲或者異常會影響到之后的任務。

如果有一個定時任務在運行時,產生未處理的異常,那么當前這個線程就會停止,那么所有的定時任務都會停止,受到影響。

PS:在這點上你可以看到,定時任務Job中異常超時等一般都是要自行處理的,以防止對其它任務的影響。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86283.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86283.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86283.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

系統分析師學習筆記

系統分析師學習筆記 目錄 系統分析師學習筆記前言1 數學與工程基礎(選擇題2-4分)1.1 圖論與應用(考選擇題)1.1.1 最小生成樹1.1.2 最短路徑1.1.3 網絡與最大流量(常考) 1.2 預測與決策(在原有基…

《仿盒馬》app開發技術分享-- 邏輯優化第三彈(83)

技術棧 Appgallery connect 開發準備 現在我們的app功能已經趨近完善,bug和缺失的細節也越來越少了,我們繼續對app進行優化,首先是我們的積分頁面,我們只實現了全部的積分展示內容,對收入和支出的積分明細并沒有進行…

(七)Dockerfile文件20個命令大全詳解

目錄 1. FROM 基于基礎鏡像構建 1.1 FROM 指令開頭 1.2 ARG和FROM使用 1.3 FROM可以多個 1.4 AS name 1.5 tag和digest 2. RUN 執行任何命令 2.1 shell和exec兩種使用方式 2.2 [OPTIONS]參數 3. CMD 指定默認執行命令 3.1 使用格式shell和exec兩種使用方式 3.2 只…

攻防世界-MISC-4-2

知識點 1.字頻分析 步驟 下載附件是一段文本, 在線網站處理:quipqiup - cryptoquip and cryptogram solver flag{classical-cipher_is_not_security_hs}

Nordic nRF54L15 SoC對包含電池監測、中斷處理和電源軌控制的定制 nPM1300 示例

1:以下是適用于 nRF Connect SDK (NCS) 的基于 Zephyr 的示例應用程序,展示了: 讀取電池電壓和狀態處理來自 nPM1300 的中斷(例如,電池或電源軌事件)控制電源軌(通過 GPIO 啟用/禁用&#xff0…

MySQL 單機部署

文章目錄 1、準備階段1.1、部署規劃1.2、硬件準備1.3、軟件準備1.4、環境清理 2、實施階段2.1、操作系統實施2.2、數據庫部署實施 3、完成 1、準備階段 1.1、部署規劃 本次部署用于測試環境,單機模式,不需要主備;MySQL數據庫版本要MySQL5.7…

小程序學習筆記:實現上拉觸底加載隨機顏色案例全解析

在前端開發中,上拉觸底加載數據是一個常見的交互需求。今天,我們就來詳細探討如何實現一個上拉觸底加載隨機顏色的案例,幫助大家更好地理解相關技術的應用。 案例效果展示 在這個案例里,我們最終要實現的效果是這樣的&#xff1…

Java+GcExcel,生成自定義工作表

引言 在當今數字化辦公和數據處理的時代,電子表格的應用無處不在。對于 Java 開發人員來說,如何高效地創建、操作和處理兼容 Microsoft Excel 的電子表格是一個常見的需求。GcExcel Java 作為葡萄城表格解決方案中的后端表格組件,為 Java 開…

跨平臺C++軟件開發之基本數據類型介紹

跨平臺C軟件開發過程中,原生數據類型的字節寬度差異是一個常見且關鍵的問題,不同操作系統、編譯器、硬件架構可能會為相同的數據類型分配不同的字節數,這可能導致代碼在移植過程中出現未定義的行為或兼容性問題。本文簡要介紹C原生數據類型字…

Java編程中的單例模式

在Java中實現單例模式有幾種方式,但最常見的是懶漢式和餓漢式。我們先來看一個簡單的懶漢式實現: public class Singleton {private static Singleton instance;private Singleton() {} // 構造方法私有化,防止外部實例化public static Sin…

原生微信小程序網絡請求與上傳接口封裝實戰指南

本文基于微信小程序原生 API,封裝 request 和 uploadFile 接口,最終實現統一請求管理、請求攔截、錯誤處理等能力。 📦 一、為什么要封裝網絡請求? 微信小程序提供了 wx.request 和 wx.uploadFile 原生 API,但直接使用…

軟件測試基礎知識詳解

🍅 點擊文末小卡片 ,免費獲取軟件測試全套資料,資料在手,漲薪更快 1、軟件測試定義 軟件測試是指在規定的條件下對程序進行操作,以發現程序錯誤,衡量軟件質量,并對其是否能滿足設計要求進行…

Spring Boot 文件上傳大小配置錯誤解決方案

問題描述 在Spring Boot應用中出現以下錯誤: Failed to bind properties under spring.servlet.multipart.max-file-size’ to org.springframework.util.unit.Datasize Property:spring.servlet.multipart.max-file-sizeValue: 10Mb Origin: URL [file:./applicat…

Matplotlib繪制矩陣圖,plt.matshow/imshow 與 ax.pcolor(pcolormesh)方法的使用

文章目錄 plt.matshow離散colorbar連續colorbar ax.pcolor簡單應用綜合應用 import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import ListedColormap#data np.random.seed(42) data np.random.rand(4, 4)plt.matshow 可以把下面的matshow換成ims…

關于 ARM64 匯編:調用流程與棧幀結構解析

一、ARM64 函數調用分析(匯編級) 寄存器規則(AArch64 ABI) 用途寄存器參數傳遞x0 ~ x7返回值x0(最多兩個:x0、x1)棧指針sp鏈接寄存器x30(lr)幀指針x29(fp&a…

Kafka vs RabbitMQ vs Redis:消息中間件全面對比與選型指南

Kafka vs RabbitMQ vs Redis:消息中間件全面對比與選型指南 一、各中間件消息流轉全過程Kafka 消息流轉全過程(含機制詳解)1. 核心組件2. 流程詳解 RabbitMQ 消息流轉全過程(含機制詳解)1. 核心組件2. 流程詳解 Redis …

【代碼級指南】從Zero-shot到Chain-of-Thought:Prompt工程全棧技術解析?

本文較長,建議點贊收藏,以免遺失。 從理論到實踐,掌握Zero-shot/Few-shot Prompt設計精髓。 一、Prompt Engineering 核心概念圖解 Prompt Engineering 三大支柱 二、Prompt 設計基礎框架 1. Prompt 核心四要素 prompt_template "&q…

sizeof()函數無法計算形參指針指向的字符串大小

給定的代碼中&#xff0c;func() 函數打印的 name_len 是 指針的大小&#xff0c;而不是字符串的長度。具體原因如下&#xff1a; 代碼分析 #include <stdio.h> #include <string.h>void func(char *name) {printf("name_len:%d", sizeof(name)); // 打…

Python打卡:Day37

知識點回顧&#xff1a; 過擬合的判斷&#xff1a;測試集和訓練集同步打印指標模型的保存和加載 僅保存權重保存權重和模型保存全部信息checkpoint&#xff0c;還包含訓練狀態 早停策略 浙大疏錦行

Android 9.0(API 28)后字重設置

在 Android 應用中設置字體字重&#xff08;Font Weight&#xff09;可以通過多種方式實現&#xff0c;下面詳細介紹各種方法及其適用場景。 1. 使用 XML 屬性設置字重 1.1 基本字重設置&#xff08;API 1&#xff09; <TextViewandroid:layout_width"wrap_content&…