为什么石英scheduleJob()执行多次?

时间:2019-01-03 01:44:31

标签: java quartz-scheduler

public class QuartzStudy implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
    System.out.println(jobExecutionContext.getJobDetail().getKey().getName() + "-" + Thread.currentThread().getName() + "-" + Thread.currentThread().getId() + "-" + new Date());
}

private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
private static Scheduler scheduler;
static {
    try {
        scheduler = schedulerFactory.getScheduler();
        scheduler.start();
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) throws SchedulerException, InterruptedException {
    JobDetail jobDetail = JobBuilder.newJob(QuartzStudy.class).withIdentity("job1").build();
    CronTrigger trigger = TriggerBuilder.newTrigger()
            .withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?").withMisfireHandlingInstructionIgnoreMisfires())
            .build();
    scheduler.scheduleJob(jobDetail, trigger);
    Thread.sleep(10000);
    scheduler.pauseJob(jobDetail.getKey());
}

}

此代码应控制台两次,然后暂停?

但是有时候控制台三遍,为什么?

job1-DefaultQuartzScheduler_Worker-1-14-Thu Jan 03 09:34:45 CST 2019

job1-DefaultQuartzScheduler_Worker-2-15-Thu Jan 03 09:34:50 CST 2019

job1-DefaultQuartzScheduler_Worker-3-16-Thu Jan 03 09:34:55 CST 2019

1 个答案:

答案 0 :(得分:1)

首先,*/5 * * * * ?的意思是Every 5 seconds starting at :00 second after the minute

您正在做Thread.sleep(10000);。这意味着main thread将暂停10秒钟。但是,由于即使在这10秒钟之内仍会收到日志,因此意味着调度程序独立于main thread。因此,在第10秒时,调度程序将创建一个线程来运行execute,并且在第10秒后,您也会暂停job。如果第一个线程(即,创建线程发生在pausing之前)首先,日志将被打印三次。而如果第二个(pausing的{​​job出现在spawning新线程的出现之前),则日志将只打印两次。这就是为什么有时日志要打印两次,有时是三次的原因。

因此,为确保仅将日志打印两次,请将睡眠时间减少到9秒。我试过下面的代码,它总是打印两次日志:

public static void main(String[] args) throws SchedulerException, InterruptedException {
        System.out.println("Main method:" + Thread.currentThread().getName() + "-" + Thread.currentThread().getId());
        JobDetail jobDetail = JobBuilder.newJob(QuartzStudy.class).withIdentity("job1").build();
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?").withMisfireHandlingInstructionIgnoreMisfires())
                .build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();    // it's better to start job once you have scheduled one
        Thread.sleep(9000);
        scheduler.pauseJob(jobDetail.getKey());
        System.out.println("Job is Paused!!!");
    }