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哪個,都不會影響另一個定時服務的正常執行。