Quartz:跳过以相同的开火时间安排的重复工作火灾

时间:2013-11-01 19:26:27

标签: java quartz-scheduler

我是Quartz的新手,并坚持重复工作。 它们是由两个具有重叠火灾时间的触发器引起的。

是否有任何Quartz“开箱即用”的功能可以防止多个附加触发器发生同一作业的重复火灾?

或者可能有一些第三方Trigger实施,它允许将时间表与适当的开火时间计算结合起来,以防止重复的火灾时间?

或许我可以以某种方式结合多个时间表?

任何解决方案都将不胜感激。

由于

为清晰起见:

public static class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("My Job at " + DateUtils.toDateTimeString(context.getFireTime()) +  " by " +
                context.getTrigger().getKey().getName());
    }
}

startScheduler() {

    final Set<Trigger> triggers = new HashSet<Trigger>();
    triggers.add(TriggerBuilder.<CronScheduleBuilder>newTrigger().withIdentity("every 3 secs").
            withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ? *")).build());
    triggers.add(TriggerBuilder.<CronScheduleBuilder>newTrigger().withIdentity("every 2 secs").
            withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ? *")).build());

    final Scheduler scheduler = new StdSchedulerFactory(properties).getScheduler();
    scheduler.scheduleJob(JobBuilder.newJob(MyJob.class).build(), triggers, false);
    scheduler.start();

}

日志:

  • 我的工作于01.11.2013T23:19:26.000每2秒
  • 我的工作于01.11.2013T23:19:27.000每3秒
  • 我的工作于01.11.2013T23:19:28.000每2秒
  • 我的工作 01.11.2013T23:19:30.000 每2秒
  • 我的工作 01.11.2013T23:19:30.001 每3秒
  • 我的工作于01.11.2013T23:19:32.000每2秒
  • 我的工作于01.11.2013T23:19:33.000每3秒
  • 我的工作于01.11.2013T23:19:34.000每2秒
  • 我的工作 01.11.2013T23:19:36.000 每2秒
  • 我的工作 01.11.2013T23:19:36.001 每3秒
  • 我的工作于01.11.2013T23:19:38.000每2秒
  • 我的工作于01.11.2013T23:19:39.000每3秒
  • 我的工作于01.11.2013T23:19:40.000每2秒
  • 我的工作 01.11.2013T23:19:42.001 每2秒
  • 我的工作 01.11.2013T23:19:42.002 每3秒

2 个答案:

答案 0 :(得分:3)

发现TriggerListener适合此任务:

scheduler.getListenerManager().addTriggerListener(new TriggerListener() {

    private Date lastFireTime = null;

    @Override
    public String getName() {
        return "prevent-duplicate-fires";
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {
    }

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        final Date fireTime = context.getScheduledFireTime();
        if (lastFireTime != null && fireTime.equals(lastFireTime)) {
            return true;
        }
        lastFireTime = fireTime;
        return false;
    }

    @Override
    public void triggerMisfired(Trigger trigger) {
    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context, Trigger.CompletedExecutionInstruction triggerInstructionCode) {
    }
});

看起来很有效:

  • 我的工作于01.11.2013T23:46:14.000每2秒
  • 我的工作于01.11.2013T23:46:15.000每3秒
  • 我的工作于01.11.2013T23:46:16.000每2秒
  • 我的工作于01.11.2013T23:46:18.000每2秒
  • ---&GT;应该开火但跳过 - 我的工作在01.11.2013T23:46:18.000每3秒
  • 我的工作于01.11.2013T23:46:20.000每2秒
  • 我的工作于01.11.2013T23:46:21.000每3秒
  • 我的工作于2013年11月1日23:46:22000每2秒
  • 我的工作于01.11.2013T23:46:24.000每2秒
  • ---&GT;应该开火但是跳过 - 我的工作在01.11.2013T23:46:24.000每3秒
  • 我的工作于01.11.2013T23:46:26.000每2秒
  • 我的工作于01.11.2013T23:46:27.000每3秒

答案 1 :(得分:0)

这是阻止作业运行的有用答案。除了从不调用重复作业的安全防范之外,还要对实现作业的类使用注释@DisallowConcurrentExecution。