【问题标题】:Java Quartz scheduled Job - disallow concurrent execution of JobJava Quartz 调度作业 - 不允许同时执行作业
【发布时间】:2015-03-05 13:50:41
【问题描述】:

我正在使用 Quartz Job 来执行特定任务。

我还在我的主应用程序类中安排它的执行,我想要完成的是不允许同时执行该作业的实例。

所以调度器应该只在其前一个实例完成时才执行作业。

这是我的工作类:

public class MainJob implements Job {

static Logger log = Logger.getLogger(MainJob.class.getName());

@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {

    GlobalConfig cfg = new GlobalConfig();

    ProcessDicomFiles processDicomFiles = new ProcessDicomFiles();  
    ProcessPdfReportFiles processPdf = new ProcessPdfReportFiles();

    try {

            log.info("1. ---- SCHEDULED JOB -- setStudiesReadyToProcess");
            processDicomFiles.setStudiesReadyToProcess();

            log.info("2. ---- SCHEDULED JOB --- distributeToStudies");
            processDicomFiles.distributeToStudies(cfg.getAssocDir());                

            ...

            //process any incoming PDF file
            log.info("11. ---- SCHEDULED JOB --- processPdfFolder");
            processPdf.processPdfFolder();

        } catch (Exception ex) {
            Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.ERROR, null, ex);
        }

    log.info(">>>>>>>>>>> Scheduled Job has ended .... <<<<<<<<<<<<<<<<<<<<");

    }
}

所以在我的应用程序的主类中,我正在启动调度程序:

...
//start Scheduler
    try {             
        startScheduler();
    } catch (SchedulerException ex) {
        log.log(Level.INFO, null, ex);
    }
...

public void startScheduler () throws SchedulerException {

        //Creating scheduler factory and scheduler
        factory = new StdSchedulerFactory();
        scheduler = factory.getScheduler();

        schedulerTimeWindow = config.getSchedulerTimeWindow();

        JobDetailImpl jobDetail = new JobDetailImpl();
        jobDetail.setName("First Job");
        jobDetail.setJobClass(MainJob.class);

        SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
        simpleTrigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
        simpleTrigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
        simpleTrigger.setRepeatInterval(schedulerTimeWindow);
        simpleTrigger.setName("FirstTrigger");

        //Start scheduler
        scheduler.start();
        scheduler.scheduleJob(jobDetail,simpleTrigger);

}

如果另一个 MainJob 实例仍在运行,我想阻止调度程序启动第二个 MainJob 实例...

【问题讨论】:

    标签: java jakarta-ee quartz-scheduler


    【解决方案1】:

    只需在 Job 类顶部使用 @DisallowConcurrentExecution 注释即可。

    请参阅此官方example 或此tutorial 关于并发作业执行。

    【讨论】:

    • 仍在寻找一种不排队工作,而是直接跳过它的方法。
    【解决方案2】:

    @DisallowConcurrentExecution 可以完成您的工作,但请注意它只会阻止您的课程在同一节点上运行两次。

    请查看Quartz 2.2 multi scheduler and @DisallowConcurrentExecution中的@ReneM 评论

    【讨论】:

    • 你从哪里得到的?阅读链接的评论,他的意思似乎是 DisallowConcurrentExecution 只有在您正确设置集群的情况下才会起作用。并不是说它不能跨节点工作。
    【解决方案3】:

    你可以实现StatefulJob或者注解DisallowConcurrentExecution

    【讨论】:

    • StatefulJob 已弃用(不知道是不是 05.2015)。 DisallowConcurrentExecution 和/或 PersistJobDataAfterExecution 是要走的路。
    【解决方案4】:

    使用@DisallowConcurrentExecution方法和@Async从Job执行时要小心

    第二个线程可能与第一个

    发生冲突

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多