2

我是 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 秒
4

2 回答 2

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 秒
  • ---> 应该开火但跳过 - 我的工作在 01.11.2013T23:46:18.000 每 3 秒
  • 我的工作在 01.11.2013T23:46:20.000 每 2 秒
  • 我的工作在 01.11.2013T23:46:21.000 每 3 秒
  • 我的工作在 01.11.2013T23:46:22.000 每 2 秒
  • 我的工作在 01.11.2013T23:46:24.000 每 2 秒
  • ---> 应该开火但跳过 - 我的工作在 01.11.2013T23:46:24.000 每 3 秒
  • 我的工作在 01.11.2013T23:46:26.000 每 2 秒
  • 我的工作在 01.11.2013T23:46:27.000 每 3 秒
于 2013-11-01T19:51:41.833 回答
0

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

于 2015-08-26T10:38:42.723 回答