一:簡述定時任務
定時任務經常有文章拿Scheduled、Quartz、Timer進行比較,確實三者的差距還是比較明顯的。而且對於一個初學者並不是很友好,特別是Scheeduled、Quartz容易搞混。這篇文章將專門介紹Spring提供的定時任務Scheduled使用方法及注意事項,後面再講解Quartz定時任務然後再做比較。至於Timer比較簡單,一筆帶過即可
二:XML配置
經過前面Spring的AOP以及事務應用講解,一般發現Spring都會提供XML配置與註解兩種方式,下面就先講解XML配置的方式實現
2.1 定時任務類
就是比較簡單的一個類方法,打印定時任務執行線程名稱和執行時間。別忘了把這個類交給Spring容器管理,當然採用註解亦或是配置文件中注入都是可以的
2.2 Spring配置文件
配置文件中聲明定時任務類、方法、執行時間是最簡單的配置。如下表所示,配置定時任務屬性說明
屬性名稱 | 屬性含義 | 備註 |
---|---|---|
ref | 引入容器中管理的定時任務對象 | |
method | 聲明定時任務執行方法的名稱 | |
fixed-delay | 定時任務執行間隔週期 | 週期從上一次定時任務執行完畢開始計算 |
fixed-rate | 定時任務執行間隔週期 | 週期從上一次定時任務開始執行計算 |
initial-delay | 第一次執行延時時長 | 系統啓動後距離多久纔開始執行第一次定時任務 |
cron | cron表達式用於指定複雜邏輯定時任務 | 下面詳細解釋 |
三:Cron表達式
3.1 表達式概述
表達式總共七個部分,含義爲:“秒 分 時 日期 月 星期幾 [年]”
其中年不是必填項,所以Cron表達式可能也只有六部分
區域 | 屬性值 | 可用特殊字符 | 備註 |
---|---|---|---|
秒 | 0-59 | * , - / | |
分 | 0-59 | * , - / | |
時 | 0-59 | * , - / | |
日期 | 1-31 | * , - / ? L W | |
月 | 1-12 | * , - / | |
星期幾 | 1-7 | * , - / L # | 1表示星期日 |
年 | 1970~2099 | * , - / | 可以省略 |
3.2 特殊字符
看不懂沒關係,概念解釋起來就是麻煩。不理解的字符查看錶達式示例即可
字符 | 含義 | 說明 |
---|---|---|
* | 所有 | |
- | 範圍 | |
? | 日期與星期幾互斥,當其中一個指定值時另外一個避免衝突需要置爲? | |
, | 與的關係 | 時上寫10,11 表示上午10點和11點 |
/ | 前面爲開始條件,後面爲間隔週期 | 時上寫1/2表示從上午1點開始,每間隔2小時執行一次 |
L | 最後 | 星期幾上寫2L 表示當月最後一個星期三 |
W | 有效工作日(週一到週五) | 只能出現在日期上,5W表示當5號爲週六非工作日時會在4號週五執行,若表示爲周天非工作日則會安排在6號週一執行。注意不能跨月 |
LW | 最後一個工作日 | |
# | 第幾個星期幾 | 5#2 表示第2個星期4執行 |
3.3 表達式示例
表達式描述 | 表達式示例 |
---|---|
每天零點執行 | 0 0 0 * * * |
每週1-5下午五點執行 | 0 0 17 ? * 2-6 |
每月最後一個週五上午10點和下午5點執行 | 0 0 10,17 ? * 6L |
3.4 星期幾說明
Spring中的周幾與Cron表達式不一致,0才表示周天。所以這是巨特麼坑,千萬別用數字來操作,草他媽。看清楚源碼的操作是將週一到周天全部轉換爲0-6數字操作的。。。。。。
四:多線程配置
4.1 線程池配置
Scheduled定時任務默認是單線程執行,那麼A任務執行可能會影響到B任務。即當B任務到達執行時間時,若A任務未執行完畢,因爲單線程原因只能等待A任務執行完畢後再開始執行。可如下通過配置定時任務線程池解決
4.2 多線程測試
如4.1所示配置兩個定時任務實例,將定時任務1修改睡眠2S,查看最後執行結果如下圖所示,不僅線程名稱切換且查看定時任務2執行間隔也爲配置時長2S。線程池id屬性爲線程名稱前綴
五:註解
5.1 開啓註解
開啓註解很簡單就是配置annotation-driven即可,多線程配置也是一致
5.2 註解使用
六:單任務多線程
6.1 單任務單線程
定時任務設定fixedRate爲2s執行一次,但是控制檯顯示爲4s執行一次,也就是線程睡眠時間。前面講到fixedRate是從上一個任務開始時間計時,按照原理來講上一個任務未執行完畢時下一個任務已經到了執行時間,而且配置文件中配置了Scheduled爲多線程,爲什麼還會是等到上一個任務執行完畢後再執行?這就是Scheduled相對於Quartz的一個特殊點,多線程指的是不同任務間多線程,相同任務只能是串行執行
6.2 單任務多線程
可以看到這裏單個定時任務已經多線程執行,結合Spring的異步執行即可實現。更多有關Spring異步執行操作後面會有文章專門介紹