1. 程式人生 > >Quartz的使用之CronTrigger觸發規則和例項多個獨立的排程器

Quartz的使用之CronTrigger觸發規則和例項多個獨立的排程器

最近因為專案原因,研究了一些quartz的基礎使用規則,今天跟大家分享一下:

首先是quartz的CronTrigger觸發規則結合quartz中的calendar介面的使用,程式碼如下:

import java.text.ParseException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.AnnualCalendar;

import cn.jbit.job.SimpleTriggerJob;

public class Test{

    public static void main(String[] args) {
        //建立排程器
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler scheduler = null;
        CronTrigger cronTrigger=null;
        //定義一個精確的任務執行時間
        try {
            scheduler = sf.getScheduler();
            cronTrigger = new CronTrigger("dayTrigger",Scheduler.DEFAULT_GROUP, "0 0/1 * ? * 2-6");
        } catch (ParseException e) {
            e.printStackTrace();
        }catch (SchedulerException e) {
            e.printStackTrace();
        }

        //AnnualCalendar用於排除年中的一天或多天
        AnnualCalendar cal = new AnnualCalendar();   

        //這裡除了需要定義一個精確的任務執行時間,還需要排除指定的日期
        Calendar calendar = GregorianCalendar.getInstance();   
        calendar.set(Calendar.MONTH, Calendar.JULY);   
        calendar.set(Calendar.DATE, 26);   

        //例項化Calendar,並加入要排除的日期
        cal.setDayExcluded(calendar, true);   

        //用Scheduler註冊Calendar 
        try {
            scheduler.addCalendar("specialDay", cal, true, true);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }   

        //將Calendar和對應的Trigger進行關聯
        cronTrigger.setCalendarName("specialDay");   

        //建立任務例項
        JobDetail jobDetail = new JobDetail( "dayJob",Scheduler.DEFAULT_GROUP,Job.class);   

        //註冊任務和觸發器
        try {
            scheduler.scheduleJob(jobDetail, cronTrigger);
            //啟動和關閉排程
            scheduler.start();
            scheduler.shutdown();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }   
    }       
}

在使用Quartz定時排程服務時,我們經常會用到CronTrigger觸發規則,定義一個精確的任務執行時間,至於CronTrigger的時間規則這裡不再贅述,大家在網上搜搜,大把的是…我們除了定義一個精確的任務執行時間,還需要排除指定的日期,例如法定節假日等,這個時候我們可以使用Quartz為我們提供的calendar介面,Quartz提供了多種實現類來滿足應用的需求:

Calendar名稱 作用
WeeklyCalendar 用於排除星期中的一天或多天
MonthlyCalendar 用於排除月份中的數天
AnnualCalendar 用於排除年中的一天或多天
HolidayCalendar 用於排除節假日

上面的程式碼演示了AnnualCalendar 實現類如何整合到我們的CronTrigger觸發規則內,其他的與之類似。

其次是如何在一個應用程式中建立多個獨立的排程器,這些獨立的排程器可以自主啟動和關閉,不會受其他排程器的影響,請大家看如下的配置:
Default Properties file for use by StdSchedulerFactory
to create a Quartz Scheduler Instance, if a different
properties file is not explicitly specified.

org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class =org.quartz.simpl.RAMJobStore

這是quartz的配置檔案,其中org.quartz.scheduler.instanceName = DefaultQuartzScheduler是配置的系統幫我們生成的scheduler的物件,當我們在程式中 scheduler = sf.getScheduler();獲取多個scheduler時,其實我們引用的是同一個物件,如果我們想要shutdown其中的某個scheduler時,其他的都會被shutdown!!!

怎麼才能獲取多個獨立的scheduler呢????經過本人辛苦查詢資料,終於找到一個非常實用的方法:

import java.text.ParseException;
import java.util.Properties;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

import cn.jbit.job.OneJob;
import cn.jbit.job.TwoJob;


public class Demo {

    public static void main(String[] args) {

        //建立排程器工廠物件,初始化quartz的配置檔案
        //獲取一個新的非預設的org.quartz.scheduler.instanceName
        //Quartz支援配置檔案初始化的
        StdSchedulerFactory ssf=new StdSchedulerFactory();
        Properties pro=new Properties();
        pro.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        pro.put("org.quartz.scheduler.instanceName", "Scheduler");
        pro.put("org.quartz.threadPool.threadCount", "10");
        try {
            ssf.initialize(pro);
        } catch (SchedulerException e1) {
            e1.printStackTrace();
        }
        //建立schedule工廠物件
        SchedulerFactory sf=new StdSchedulerFactory();
        //建立schedule物件
        Scheduler scheduler =null;
        //crontriggr觸發規則
        CronTrigger ct=null;
        //simpletrigger觸發規則
        SimpleTrigger st=null;
        try {
            ct=new CronTrigger("dayTrigger2","group2", "0/10 * * ? * 2-6");
            st=new SimpleTrigger("dayTrigger3","group3",2,5000);
            scheduler = sf.getScheduler();
            updateSche=ssf.getScheduler();
            System.out.println(updateSche.getSchedulerName());
        } catch (SchedulerException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        JobDetail jobDetail2=new JobDetail("dayjob2","group2",OneJob.class);
        JobDetail jobDetail3=new JobDetail("dayjob3","group3",TwoJob.class);
        try {
            scheduler.scheduleJob(jobDetail2, ct);
            updateSche.scheduleJob(jobDetail3,st);
            //啟動和關閉排程
            scheduler.start();
            updateSche.start();
            //(A)scheduler.shutdown(true);
            //(B)updateSche.shutdown(true);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

對於以上的A、B兩句程式碼,不管你shutdown哪個,都不會影響另一個定時服務的正常執行。