关于Cron表达式和quartzmanage
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Cron表达式和quartzmanage相关的知识,希望对你有一定的参考价值。
1. Cron表达式解释一下,不要是从网上的直接Copy过来。最好是自己写出来的心得。2. quartzmanage实现定时任务的同时时候,具体是怎么实现数据库中数据锁定的,最好能有点核心代码(通过Spring配置)。谢谢!
参考技术A cron表达式Quartz的cron表达式
一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。
字段
允许值
允许的特殊字符
秒
0-59
,
-
*
/
分
0-59
,
-
*
/
小时
0-23
,
-
*
/
日期
1-31
,
-
*
?
/
L
W
C
月份
1-12
或者
JAN-DEC
,
-
*
/
星期
1-7
或者
SUN-SAT
,
-
*
?
/
L
C
#
年(可选)
留空,
1970-2099
,
-
*
/
表达式
意义
"0
0
12
*
*
?"
每天中午12点触发
"0
15
10
?
*
*"
每天上午10:15触发
"0
15
10
*
*
?"
每天上午10:15触发
"0
15
10
*
*
?
*"
每天上午10:15触发
"0
15
10
*
*
?
2005"
2005年的每天上午10:15触发
"0
*
14
*
*
?"
在每天下午2点到下午2:59期间的每1分钟触发
"0
0/5
14
*
*
?"
在每天下午2点到下午2:55期间的每5分钟触发
"0
0/5
14,18
*
*
?"
在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0
0-5
14
*
*
?"
在每天下午2点到下午2:05期间的每1分钟触发
"0
10,44
14
?
3
WED"
每年三月的星期三的下午2:10和2:44触发
"0
15
10
?
*
MON-FRI"
周一至周五的上午10:15触发
"0
15
10
15
*
?"
每月15日上午10:15触发
"0
15
10
L
*
?"
每月最后一日的上午10:15触发
"0
15
10
?
*
6L"
每月的最后一个星期五上午10:15触发
"0
15
10
?
*
6L
2002-2005"
2002年至2005年的每月的最后一个星期五上午10:15触发
"0
15
10
?
*
6#3"
每月的第三个星期五上午10:15触发
秒(0~59)
分钟(0~59)
小时(0~23)
天(月)(0~31,但是你需要考虑你月的天数)
月(0~11)
天(星期)(1~7
1=SUN
或
SUN,MON,TUE,WED,THU,FRI,SAT)
一个完整的例子
“0
0
12
?
*
WED”表示每个星期三中午12点
有些子表达式能包含一些范围或列表
例如:子表达式(天(星期))可以为
“MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT”
“*”字符代表所有可能的值
因此,“*”在子表达式(月)里表示每个月的含义,“*”在子表达式(天(星期))表示星期的每一天
“/”字符用来指定数值的增量
例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟
在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样
“?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值。(个人理解:如果是这个符号,则表达式的含义说明这个值不用考虑,相当于为了满足表达式共6部分的占位符号)
当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”
“L”
字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写
但是它在两个子表达式里的含义是不同的。
在天(月)子表达式中,“L”表示一个月的最后一天
在天(星期)自表达式中,“L”表示一个星期的最后一天,也就是SAT
如果在“L”前有具体的内容,它就具有其他的含义了
例如:“6L”表示这个月的倒数第6天,“FRIL”表示这个月的最一个星期五
注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题
Quartz 和 springboot schedule中的cron表达式关于星期(周几)的不同表示
一.Quartz中cron 表达式分析:
quartz 官方源码(org.quartz.CronExpression)解释:
Cron expressions are comprised of 6 required fields and one optional field separated by white space. The fields respectively are described as follows:
(翻译:Cron表达式由6个必填字段和一个由空格分隔的可选字段组成。 这些字段分别描述如下:)
由上表格可见,Quartz中cron表达式可以由最多7个字段构成,即:秒、分、时、日、月、周、年,最后一个字段”年“则可以为空;
对于周几,即 “Day-of-Week” 其值 1,2,3,4,5,6,7分别表示 “SUN,MON,TUE,WED,THU,FRI,SAT”;
二. SpringBoot schedule cron表达式分析:
解析cron expression的源码(org.springframework.scheduling.support.CronSequenceGenerator.class):
1 private void parse(String expression) throws IllegalArgumentException 2 String[] fields = StringUtils.tokenizeToStringArray(expression, " "); 3 if (!areValidCronFields(fields)) 4 throw new IllegalArgumentException(String.format( 5 "Cron expression must consist of 6 fields (found %d in "%s")", fields.length, expression)); 6 7 setNumberHits(this.seconds, fields[0], 0, 60); 8 setNumberHits(this.minutes, fields[1], 0, 60); 9 setNumberHits(this.hours, fields[2], 0, 24); 10 setDaysOfMonth(this.daysOfMonth, fields[3]); 11 setMonths(this.months, fields[4]); 12 setDays(this.daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8); 13 if (this.daysOfWeek.get(7)) 14 // Sunday can be represented as 0 or 7 15 this.daysOfWeek.set(0); 16 this.daysOfWeek.clear(7); 17 18
由上面的代码看Cron表达式必须由6个字段组成,没有‘year’!,重点看setDays方法,此方法转换dayOfWeek的值,找到replaceOrdnal方法源码:
1 /** 2 * Replace the values in the comma-separated list (case insensitive) 3 * with their index in the list. 4 * @return a new String with the values from the list replaced 5 */ 6 private String replaceOrdinals(String value, String commaSeparatedList) 7 String[] list = StringUtils.commaDelimitedListToStringArray(commaSeparatedList); 8 for (int i = 0; i < list.length; i++) 9 String item = list[i].toUpperCase(); 10 value = StringUtils.replace(value.toUpperCase(), item, "" + i); 11 12 return value; 13
上面的代码直接将cronExpression字符串中的 "SUN,MON,TUE,WED,THU,FRI,SAT"分别替换成了”0,1,2,3,4,5,6“;
而且parse方法中注释”// Sunday can be represented as 0 or 7” 即:周日均可用‘0’或’7‘表示。
所以对于springBoot schedule 其值 1,2,3,4,5,6,7分别表示 “MON,TUE,WED,THU,FRI,SAT,SUN”;0也表示SUN;
以上是关于关于Cron表达式和quartzmanage的主要内容,如果未能解决你的问题,请参考以下文章
Quartz 和 springboot schedule中的cron表达式关于星期(周几)的不同表示