如果作业已在执行,则执行Veto

时间:2016-02-18 13:23:21

标签: java quartz-scheduler

如果同一作业的另一个实例已在执行(如果正在运行相同的“JobDetail”),我想跳过作业执行。我知道注释“@DisallowConcurrentExecution”避免同时执行同一个作业。但缺点是,当作业(执行的作业时间较长,然后触发周期性)完成后,作业将立即重新执行。我希望在下一个计划开火时间内执行该工作。

实施例

  

工作实施

public class LongJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        try {
            System.out.println("Executed: " + LocalDateTime.now().toString());
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  

调度

JobDetail job2 = JobBuilder.newJob(LongJob.class)
        .withIdentity("job2")
        .build();

Trigger trigger2 = TriggerBuilder.newTrigger()
        .forJob(job2)
        .startNow()
        .withIdentity("job2-trigger")
        .withSchedule(
                CronScheduleBuilder.cronSchedule("0/3 * * ? * *")
                        .withMisfireHandlingInstructionIgnoreMisfires())
        .build();
scheduler.scheduleJob(job2, trigger2); 
  

预期输出

Executed: 2016-02-18T10:11:15
Executed: 2016-02-18T10:11:21
Executed: 2016-02-18T10:11:27
Executed: 2016-02-18T10:11:33
  

使用@DisallowConcurrentExecution输出

Executed: 2016-02-18T10:11:15
Executed: 2016-02-18T10:11:20
Executed: 2016-02-18T10:11:25
Executed: 2016-02-18T10:11:30

我的解决方案

我使用Trigger Listeners制作了一个解决方案,但我想知道是否有一个更简单的解决方案。在这种方法中,我会为触发相同作业的每组触发器使用一个监听器实例(我可以使用不同的触发器来解决我的“更大”问题,避免对不同的作业使用相同的触发器。)

class CustomTriggerListener extends TriggerListenerSupport {

    private JobExecutionContext lastJobExecutionContext;

    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        boolean vetoExecution = false;
        if (lastJobExecutionContext == null) {
            lastJobExecutionContext = context;
        } else {
            boolean lastJobIsDone = lastJobExecutionContext.getJobRunTime() >= 0;

            if (lastJobIsDone) {
                lastJobExecutionContext = context;
            } else {
                vetoExecution = true;
            }
        }

        return vetoExecution;
    }

    @Override
    public String getName() {
        return "CustomTriggerListener";
    }

}

0 个答案:

没有答案