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

回到顶部