Java 如果作业已在执行,则否决执行

Java 如果作业已在执行,则否决执行,java,quartz-scheduler,Java,Quartz Scheduler,如果同一作业的另一个实例已经在执行(如果相同的“JobDetail”正在运行),我想跳过作业执行。我知道注释“@DisallowConcurrentExecution”避免了同一作业的并发执行。但缺点是,当作业(执行时间比触发器周期长的作业)完成时,作业将立即重新执行。我希望这项工作能在下一个时间内完成 例子 工作执行 日程安排 预期产量 使用@DisallowConcurrentExecution输出 我的解决方案 我使用触发器侦听器提出了一个解决方案,但我想知道是否有更简单的解决方案。在这种

如果同一作业的另一个实例已经在执行(如果相同的“JobDetail”正在运行),我想跳过作业执行。我知道注释“@DisallowConcurrentExecution”避免了同一作业的并发执行。但缺点是,当作业(执行时间比触发器周期长的作业)完成时,作业将立即重新执行。我希望这项工作能在下一个时间内完成

例子 工作执行

日程安排

预期产量

使用@DisallowConcurrentExecution输出

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


您尝试使用某种信号量并检查,即当作业开始运行时,它会引发信号量,并在完成后再次删除它。当第二个作业启动并看到信号量时,它会立即停止。这也可以工作,但我更喜欢CustromTrigger方法。但是CustomTrigger不能与触发多个作业的触发器一起工作,信号量解决方案会尝试使用某种信号量并检查,即当作业开始运行时,它会引发信号量,并在完成后再次删除它。当第二个作业启动并看到信号量时,它会立即停止。这也可以工作,但我更喜欢CustromTrigger方法。但是CustomTrigger不会与触发多个作业的触发器一起工作,信号量解决方案会
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
Executed: 2016-02-18T10:11:15
Executed: 2016-02-18T10:11:20
Executed: 2016-02-18T10:11:25
Executed: 2016-02-18T10:11:30
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";
    }

}