Quartz Java恢复作业会执行多次
对于我的应用程序,我创建作业并使用CronTriggers计划它们。每个作业只有一个触发器,并且作业名称和触发器名称都相同。没有作业共享触发器。
现在,当我创建像这样的cron触发器 它指示作业每秒钟执行一次,效果很好。
当我第一次通过以下方式暂停工作时,问题就出现了:
scheduler.pauseJob(jobName, jobGroup);
然后假设50秒后恢复工作:
scheduler.resumeJob(jobName, jobGroup);
我看到的是,在这50秒钟中,作业没有按要求执行。但是当我恢复工作的那一刻,我看到同时执行了50次工作!!!
我以为这是由于不触发指令的默认设置引起的,但即使在创建触发器时将触发器的不触发指令设置为此:
trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
发生同样的事情。谁能建议解决此问题的方法?
回答:
在CronTrigger
通过记住的作品nextFireTime
。创建触发器后,将对其nextFireTime
进行初始化。每次触发作业nextFireTime
都会更新。由于暂停时未触发作业,因此nextFireTime
保持“旧”状态。因此,恢复作业后,触发器将返回每个旧的触发器时间。
问题是,触发器不知道它已被暂停。为了克服这个问题,进行了不点火处理。恢复作业后,updateAfterMisfire()
将调用触发器的方法来更正nextFireTime
。但是,如果nextFireTime
和现在之间的差小于misfireThreshold,则不是这样。这样就永远不会调用该方法。此阈值的默认值为60,000。因此,如果您的暂停时间超过60s,一切都会好起来的。
由于您有问题,我认为没有。;)要解决此问题,您可以修改阈值或在周围使用简单的包装器CronTrigger
:
public class PauseAwareCronTrigger extends CronTrigger { // constructors you need go here
@Override
public Date getNextFireTime() {
Date nextFireTime = super.getNextFireTime();
if (nextFireTime.getTime() < System.currentTimeMillis()) {
// next fire time after now
nextFireTime = super.getFireTimeAfter(null);
super.setNextFireTime(nextFireTime);
}
return nextFireTime;
}
}
以上是 Quartz Java恢复作业会执行多次 的全部内容, 来源链接: utcz.com/qa/414008.html