2017-06-15 77 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換句話說)的註釋。