Cron表达式中*和?的区别 | Baeldung
Cron表达式中*和?的区别 | Baeldung
1. 概述
使用cron调度器,我们可以自动化那些我们本需要手动处理的重复性任务。此外,cron表达式允许我们安排任务在所需的日期和时间执行。
在Java中安排任务,我们通常使用Quartz库。它是一个完全用Java编写的作业调度的开源解决方案。此外,如果我们使用Spring框架,我们可以使用@Scheduled注解轻松安排任务。
尽管cron表达式是安排任务的强大方式,但其语法有时可能会令人困惑和不知所措。
在本教程中,我们将探讨cron表达式中?和*符号的区别。
2. Cron表达式的字段
在我们深入之前,让我们先探索一下可能出现在cron表达式中的字段。
在Quartz中,cron表达式表示一个字符串,涉及多达七个字段,由空格分隔,每个字段代表特定的日期和时间单位:
| 字段 | 必需 | 允许值 | 允许的特殊字符 |
|---|---|---|---|
| 秒 | 是 | 0-59 | , – * / |
| 分钟 | 是 | 0-59 | , – * / |
| 小时 | 是 | 0-23 | , – * / |
| 月份中的天 | 是 | 1-31 | , – * / ? L W |
| 月份 | 是 | 0-11 (或JAN-DEC) | , – * / |
| 星期中的天 | 是 | 1-7 (或SUN-SAT) | , – * / ? L C # |
| 年 | 否 | 1970-2099 (或空) | , – * / |
如上表所示,除了指定年份的字段外,所有字段都是必需的。如果我们不提供值,任务将每年执行一次。
此外,Unix cron表达式的语法有点不同:
| 字段 | 必需 | 允许值 | 允许的特殊字符 |
|---|---|---|---|
| 分钟 | 是 | 0-59 | , – * / |
| 小时 | 是 | 0-23 | , – * / |
| 月份中的天 | 是 | 1-31 | , – * / |
| 月份 | 是 | 1-12 (或JAN-DEC) | , – * / |
| 星期中的天 | 是 | 0-6 (或SUN-SAT) | , – * / |
Unix cron表达式由五个字段组成,后面跟着我们想要执行的命令。与Quartz不同,没有特定的字段来指定秒和年份。它专注于为当年安排任务。
值得注意的是,Unix cron表达式不允许在表达式中出现?符号。
在接下来的部分中,我们将主要关注使用Quartz库的cron表达式。
3. Cron表达式中的?
接下来,让我们研究cron表达式中的问号符号(?)。简单来说,它表示没有特定的值。
我们只能在指定月份中的天和星期中的天的字段中使用它。
然而,需要注意的是,月份中的天和星期中的天字段是互斥的。换句话说,我们不能在同一个表达式中为这两个字段指定值。
例如,以下表达式会导致错误:
0 30 10 1 OCT 2 2023
此外,为了更容易理解表达式,让我们在表格中看到它:
| 秒 | 分钟 | 小时 | 月份中的天 | 月份 | 星期中的天 | 年 |
|---|---|---|---|---|---|---|
| 0 | 30 | 10 | 1 | OCT | 2 | 2023 |
我们为月份中的天和星期中的天参数都设置了值,这在Quartz中是不支持的。
即使我们使用正确的星期几的月份中的天:
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 | OCT | ? | 空 |
任务在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表达式中*和?特殊字符之间的主要区别:
| *符号 | ?符号 |
|---|---|
| 代表特定字段的所有允许值 | 表示没有特定值 |
| 可以在任何字段中使用 | 只能在代表月份中的天和星期中的天的字段中使用 |
| 用于指定字段中的所有值 | 用于设置空值 |
| 可以在同一个表达式中出现多次 | 每个表达式中只能存在一个 |
6. 结论
在本文中,我们学习了cron表达式中星号和问号特殊字符的区别。
总之,我们将在cron表达式的字段中使用*来包括该特定字段的所有允许值。相反,?表示没有特定值,只能用于月份中的天和星期中的天字段。
由于Quartz不支持这两个字段的实现,我们需要在其中一个字段中使用?来留空该字段。