Quartz Java重新开始工作多次

Sav*_*sis 22 java scheduling scheduled-tasks quartz-scheduler

对于我的应用程序,我创建作业并使用CronTriggers安排它们.每个作业只有一个触发器,作业名称和触发器名称都相同.没有工作共享触发器.

现在当我创建像这样的"0/1****?"的cron触发器时 它指示作业每秒执行一次,它工作得很好.

当我第一次暂停工作时,问题就出现了:

scheduler.pauseJob(jobName, jobGroup);
Run Code Online (Sandbox Code Playgroud)

然后让我们说50秒后恢复工作:

scheduler.resumeJob(jobName, jobGroup);
Run Code Online (Sandbox Code Playgroud)

我看到的是,在这50秒内,作业没有按要求执行.但是,当我恢复工作的那一刻,我同时看到了50份执行工作!

我认为这是由于失火指令的默认设置,但即使在创建时将触发器的失火指示设置为:

trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
Run Code Online (Sandbox Code Playgroud)

同样的事情发生了.任何人都可以建议一种解决方法吗?

Edu*_*rch 30

CronTrigger通过记住的作品nextFireTime.创建触发器后,nextFireTime将初始化.每次触发作业nextFireTime都会更新.由于在暂停时未触发作业nextFireTime仍为"旧".因此,在您恢复作业后,触发器将返回每个旧的触发时间.

问题是,触发器不知道它正在暂停.为了解决这个问题,有这种失火处理.恢复作业后,updateAfterMisfire()将调用触发器的方法来纠正nextFireTime.但是如果nextFireTime和现在之间的差异小于misfireThreshold不行.然后永远不会调用该方法.此阈值的默认值为60,000.因此,如果您的暂停时间超过60秒,一切都会好的.

既然你有问题,我认为不是.;)要解决此问题,您可以修改阈值或使用简单的包装器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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你太多:)这就像一个魅力.像暂停工作这样简单的任务会产生这样的问题,这似乎很奇怪. (4认同)

ska*_*man 5

如果暂停作业,触发器将继续触发,但执行将排队,直到作业恢复.这不是失误的触发器,因此设置将不起作用.

我认为,您想要以编程方式禁用或删除cron触发器,而不是暂停作业.如果要恢复,请重新添加触发器.