问题陈述:
在使用quartz工具包来获取cron表达式的下次执行时间时,发现增量的功能和预期不一致,并不是“每隔多少秒”。而是“从x秒开始每隔多少秒执行一次,当达到最大值后再次从x秒开始”,并不能基于一个beginTime和cron做持续步增。
获取的方法如下:
CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
try {
cronTriggerImpl.setCronExpression(cronExpression);
cronTriggerImpl.setStartTime(beginTime);
cronTriggerImpl.setEndTime(endTime);
Date date = cronTriggerImpl.getFireTimeAfter(baseTime);
} catch (ParseException e) {
}
Cron表达式是:
*/7 * * * * ?
获取的结果是:
16:12:00,16:12:07,16:12:14,16:12:21,16:12:28,16:12:35,16:12:42,16:12:49,
16:12:56,
16:13:00,
16:13:07,
16:13:14,16:13:21,16:13:28,16:13:35,16:13:42,16:13:49,16:13:56,16:14:00,16:14:07
具体的原因如下:
其实cron表达式”*/7 * * * * ?”等价于”0/7 * * * * ?”
分析CronTriggerImpl和CronExpression的buildExpression、storeExpressionVals、addToSet等方法可知:
步增量a/b处理过程如下:
1,步增量为b,步增的起始值为a(默认值为0,*也是0)。
2,依据起始值,步增值,该位置的最大值生成一个TreeSet,保存该位置的可取值。
在生成可执行时间时,由这些时间组合形成。所以cron在该位置的取值是固定的几个值。
解决方案:
1,Spring Scheduled
@Scheduled(fixedRate = 9000)
从启动起,每9000ms执行一次
2,基于Calendar计算
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
cal.add(Calendar.MILLISECOND,90000);