* 和 ? 之間的區別在 Cron 表達式中
1. 概述
使用 cron 調度程序,我們可以自動執行原本需要手動處理的重複任務。此外,cron 表達式允許我們安排作業在所需的日期和時間執行。
對於Java中的作業調度,我們通常使用Quartz函式庫。它是完全用 Java 編寫的作業調度的開源解決方案。此外,如果我們使用 Spring 框架,我們可以使用@Scheduled
註解來輕鬆安排任務。
儘管 cron 表達式代表了一種強大的任務安排方式,但它的語法有時可能會令人困惑和不知所措。
在本教程中,我們將研究 ? 之間的差異。以及 cron 表達式中的 * 符號。
2. Cron 表達式中的字段
在深入研究之前,讓我們先探討一下 cron 表達式中可能出現的欄位。
在 Quartz 中,cron 表達式表示一個字串,最多涉及七個由空格分隔的字段,每個字段表示日期和時間的特定單位:
場地 | 必需的 | 允許值 | 允許的特殊字符 |
---|---|---|---|
秒數 | 是的 | 0-59 | , – * / |
分分鐘 | 是的 | 0-59 | , – * / |
小時 | 是的 | 0-23 | , – * / |
每月的某一天 | 是的 | 1-31 | , – * / ?長波 |
月 | 是的 | 0-11(或一月至十二月) | , – * / |
星期幾 | 是的 | 1-7(或週日至週六) | , – * / ? LC# |
年 | 不 | 1970-2099(或空) | , – * / |
正如我們在上表中看到的,除了指定年份的欄位之外,所有欄位都是必填的。如果我們不提供值,該作業將每年執行一次。
此外,Unix cron 表達式的語法有點不同:
場地 | 必需的 | 允許值 | 允許的特殊字符 |
---|---|---|---|
分分鐘 | 是的 | 0-59 | , – * / |
小時 | 是的 | 0-23 | , – * / |
每月的某一天 | 是的 | 1-31 | , – * / |
月 | 是的 | 1-12(或一月至十二月) | , – * / |
星期幾 | 是的 | 0-6(或週日-週六) | , – * / |
Unix cron 表達式由五個欄位組成,後面跟著我們要執行的命令。與 Quartz 不同,我們沒有指定秒和年的特定欄位。重點是安排今年的任務。
值得注意的是,Unix 中的 cron 表達式不允許 ?符號出現在表達式中。
在接下來的部分中,我們將主要關注 Quartz 庫的 cron 表達式。
3. ?
在 Cron 表達式中
接下來,讓我們檢查 cron 表達式中的問號符號 ( ?
)。簡單來說,它不代表任何特定的值。
我們只能在指定月份和星期幾的欄位中使用它。
但是,請務必注意,月份中的某一天和星期幾字段是互斥的。換句話說,我們不能在同一表達式中指定兩個欄位的值。
例如,以下表達式會導致錯誤:
0 30 10 1 OCT 2 2023
另外,為了方便理解這個表達式,我們看一下表:
秒數 | 分分鐘 | 小時 | 每月的某一天 | 月 | 星期幾 | 年 |
---|---|---|---|---|---|---|
0 | 30 | 10 | 1 | 華僑城 | 2 | 2023年 |
我們為月份中的某一天和星期幾參數設定值,Quartz 不支援這些值。
即使我們使用正確工作日的月份中的某一天,cron 表達式也將無效:
0 30 10 30 OCT 2 2023
此處,2023 年 10 月 30 日是星期一,但該表達式仍然無效。
此外,由於我們需要為兩個欄位設定值,因此我們需要將?
其中之一上的符號表示該值未設定。我們設定的字段?
將被忽略:
0 0 0 30 OCT ?
從範例中可以看出,該作業在每年 10 月 30 日午夜運行。
另外, ?
在 cron 表達式中只能出現一次。用?
設定這兩個值也會導致錯誤:
0 30 * ? OCT ?
4. Cron表達式中的*
另一方面,cron 表達式中的星號 ( *
) 表示所有值。換句話說,我們將使用它來設定為特定欄位定義的所有值。
此外,與?
,我們可以在 cron 表達式的任何欄位中使用*
。
作為範例,讓我們建立一個 cron 表達式,在其中設定表示小時的欄位中的所有值:
0 30 * 1 OCT ?
接下來我們以表格形式來看一下:
秒數 | 分分鐘 | 小時 | 每月的某一天 | 月 | 星期幾 | 年 |
---|---|---|---|---|---|---|
0 | 30 | * | 1 | 華僑城 | ? | 空的 |
該作業於 10 月 1 日每小時 30 分 0 秒執行。
此外,我們也可以將*
用於多個欄位:
* * * * OCT ?
該作業在 10 月每天每秒運行一次。
4.1. Linux Cron 中的月份和星期幾
當涉及 Linux cron 中的月份中的某一天和工作日欄位時,它們的行為與 Quartz 中的行為不同。
首先,它們並不互相排斥。我們可以在同一個 cron 表達式中設定這兩個值。
其次,如果兩個欄位都包含星號以外的值,則它們形成一個並集:
30 10 1 10 5
上面範例中的作業在 10 月 1 日和每個星期五的 10:30 執行。
最後,如果其中一個值以星號開頭,則它們形成一個交集:
30 10 */1 * 1
在此,僅當週一為該作業時,該作業才會在該月的每一天的 10:30 運行。
5. *
和?
的比較
最後,讓我們列出*
和?
之間的主要區別cron 表達式中的特殊字元:
* 符號 |
這? 象徵 |
---|---|
代表特定欄位的所有允許值 | 表示沒有具體值 |
可用於任何領域 | 只能在表示月份中的某一天和星期幾的欄位中使用 |
用於指定欄位中的所有值 | 用於設定空值 |
可以在同一個表達式中多次出現 | 每個表達式只能存在一個 |
六,結論
在本文中,我們了解了 cron 表達式中星號和問號特殊字元的差異。
總而言之,我們在 cron 表達式的欄位中使用*
來包含該特定欄位的所有允許值。相反, ?
表示沒有特定值,並且只能在“day of Month”和“day of week”欄位中使用。
由於 Quartz 不支援這兩個欄位的實現,因此我們需要使用?
其中之一將欄位留空。