Quartz Scheduler 当前作业正在增加

Quartz Scheduler current jobs are increasing

我已经使用 quartz 创建了一个示例程序。主程序将触发一个控制器作业,每 3 秒 运行s 并且我已经从这个控制器在 cron 计划中安排了一个作业到 运行。

我的要求是,如果作业的一个实例是 运行ning,则下一个实例不应启动。因此,我从调度程序上下文当前活动的作业中迭代了 jobcontext 列表,并检查是否存在与当前作业实例匹配的作业实例,然后简单地 return.

为了测试这一点,我在各自的作业中实现了线程休眠,这比预定时间要长。作业实例没有像预期的那样并行触发,但我的调度程序上下文当前活动的作业列表在不断增加。我需要帮助 reducing/keep 检查当前活动作业的大小。

我的程序如下

主程序:

package com.test.objectpool;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class CronTriggerExample {

    public static void main(String[] args) throws Exception {
        JobDetail job = JobBuilder.newJob(QuartzSchedulerController.class).withIdentity("job-a-cntrl", "group.12-1")
                .build();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger.1", "group.12-1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        scheduler.start();
        scheduler.scheduleJob(job, trigger);

    }
}

控制器作业:

package com.test.objectpool;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;

public class QuartzSchedulerController implements Job {

    public void execute(JobExecutionContext context) {

        try {
            context.getScheduler().getCurrentlyExecutingJobs().forEach(job -> {
                if (job.getTrigger().equals(context.getTrigger()) && !job.getJobInstance().equals(this)) {
                    System.out.println("There's another instance running crontroller , so leaving" + this);
                    return;
                }
            });

            Thread.sleep(4000);
            System.out.println("Inside scheduler controller --- >> ");
            Scheduler scheduler = context.getScheduler();

            JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("hello-1.1", "group1-1.2").build();
            JobKey jbK = job.getKey();
            System.out.println("Job key is " + jbK);
            if (!scheduler.checkExists(jbK)) {
                System.out.println("Scheduling hellow world -----");
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger.1", "group1-1.2").withSchedule(
                        CronScheduleBuilder.cronSchedule("0/2 * * * * ?").withMisfireHandlingInstructionDoNothing())
                        .build();

                scheduler.scheduleJob(job, trigger);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

最后由控制器控制的工作class是:

package com.test.objectpool;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;

public class HelloJob implements Job {
    private static int count = 0;

    public void execute(JobExecutionContext context) throws JobExecutionException {

        try {
            List<JobExecutionContext> jobs = context.getScheduler().getCurrentlyExecutingJobs();
            System.out.println("The size of the job queue is " + jobs.size());
            for (JobExecutionContext job : jobs) {
                if (job.getTrigger().equals(context.getTrigger()) && !job.getJobInstance().equals(this)) {
                    System.out.println("There's another instance running, so leaving" + this);
                    return;
                }

            }
            Date dt = Calendar.getInstance().getTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
            String uniqueID = UUID.randomUUID().toString();
            System.out.println("Hello Quartz!" + context.getScheduledFireTime() + " :With count " + count
                    + " :Current date " + sdf.format(dt) + " UUID =" + uniqueID);

            Thread.sleep(10000);
            // System.out.println("Hello Quartz!"+
            // context.getScheduledFireTime());

            System.out.println("Completed " + "With count " + count + " UUID : " + uniqueID);
            count++;
        } catch (SchedulerException | InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

}

问题是使用这种方法 context.getScheduler().getCurrentlyExecutingJobs() 会不断增加。

只需用 @DisallowConcurrentExecution 注释您的工作,如下所示:

@DisallowConcurrentExecution
public class QuartzSchedulerController implements Job {
    ...

并且 Quartz 将处理不超过 运行 1 个实例。

An annotation that marks a Job class as one that must not have multiple instances executed concurrently (where instance is based-upon a JobDetail definition - or in other words based upon a JobKey).