2017-06-15 185 views
1

我已经使用石英创建了一个示例程序。如果主程序触发一个每3秒运行一次的控制器作业,并且从该控制器运行,我已经安排了一个作业以cron时间表运行。石英调度器当前作业正在增加

我的要求是,如果一个作业实例正在运行,那么下一个实例不应该启动。所以我已经从调度程序上下文当前活动作业迭代了jobcontext列表,并且检查是否存在任何与当前作业实例匹配的作业实例,然后简单地返回。

为了测试这个,我在相应的作业中实现了超过预定时间的线程睡眠。作业实例没有被预期的并行触发,但是我的调度程序上下文当前活动作业列表正在不断增加。我需要帮助减少/保持当前活动作业的大小。

我的程序如下。

主程序:

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(); 
     } 
    } 
} 

最后由控制器控制的作业类是:

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()不断增加。

回答

2

只是@DisallowConcurrentExecution注释你的工作,像这样:

@DisallowConcurrentExecution 
public class QuartzSchedulerController implements Job { 
    ... 

和Quartz将采取不运行超过1个实例的照顾。

标志着一个Job类作为一个必须不具有同时执行多个实例(其中,例如是基于-在一个JobDetail定义 - 或基于JobKey换句话说)的注释。