Java定時任務Quartz二
1.Trigger通用屬性
Trigger的觸發器通用屬性:JobKey——job例項的標識,觸發器被觸發時,該指定的job例項會執行;StartTime——表示觸發器的時間表首次被觸發的時間,它的值的型別是Java.util.Date;EndTime——指定觸發器不再被觸發的時間,它的值的型別是Java.util.Date;Job示例程式碼如下:
package com.luna.timer.quarts; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.Trigger; public class HelloJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { //列印當前執行時間 Date startTime = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("任務執行時間為:"+sf.format(startTime)); Trigger currentTrigger = context.getTrigger(); System.out.println("Start Time is:"+sf.format(currentTrigger.getStartTime())); System.out.println("End Time is:"+sf.format(currentTrigger.getEndTime())); JobKey jobKey = currentTrigger.getJobKey(); System.out.println("JobKey info---"+"jobName:"+jobKey.getName()+"jobGroup:"+jobKey.getGroup()); } }
Trigger示例程式碼如下:
package com.luna.timer.quarts; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class HelloScheduler { public static void main(String[] args) throws SchedulerException { // 建立一個JobDetail例項與HelloJob類繫結 JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build(); //列印當前時間 Date startTime = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("列印當前時間:"+sf.format(startTime)); //獲取當前時間3秒後的時間 startTime.setTime(startTime.getTime()+3000); //獲取當前時間6秒後的時間 Date endDate = new Date(); endDate.setTime(endDate.getTime()+6000); // 建立一個Trigger例項,定義該Job立即執行,且每隔兩秒鐘執行一次直到永遠 Trigger trigger = TriggerBuilder.newTrigger(). withIdentity("mtTrigger", "group1"). startAt(startTime).endAt(endDate). withSchedule(SimpleScheduleBuilder.simpleSchedule(). withIntervalInSeconds(2).repeatForever()).build(); //建立scheduler例項 SchedulerFactory sFactory = new StdSchedulerFactory(); Scheduler scheduler = sFactory.getScheduler(); scheduler.start(); scheduler.scheduleJob(jobDetail,trigger); } }
2.淺談SimpleTrigger
SimpleTrigger:在一個指定時間段內執行一次作業任務,或者是在指定的時間間隔內多次執行作業任務。建立定時任務:距離當前時間4秒之後執行且僅執行一次,程式碼如下:
package com.luna.timer.quarts; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class HelloJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { //列印當前執行時間 Date startTime = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("任務執行時間為:"+sf.format(startTime)); System.out.println("Hello World!"); } }
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//獲取距離當前時間4秒之後的時間
startTime.setTime(startTime.getTime()+4000L);
// 建立一個Trigger例項,距離當前時間4秒鐘後執行且僅執行一次任務
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").startAt(startTime).build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
建立定時任務:距離當前時間4秒之後執行之後每隔兩秒執行一次,距離當前時間6秒之後停止執行,程式碼如下:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//獲取距離當前時間4秒之後的時間
startTime.setTime(startTime.getTime()+4000L);
// 建立一個Trigger例項,距離當前時間4秒鐘後執行任務,之後每隔兩秒執行一次任務
//withRepeatCount方法引數:SimpleTrigger.REPEAT_INDEFINITELY永遠執行下去,若設定為具體數字則就執行幾次
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").startAt(startTime).
withSchedule(SimpleScheduleBuilder.simpleSchedule().
withIntervalInSeconds(2).withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)).build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
建立定時任務:距離當前時間4秒之後執行之後每隔兩秒執行一次,永遠執行下去,程式碼如下:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//獲取距離當前時間4秒之後的時間
startTime.setTime(startTime.getTime()+4000L);
//獲取6秒之後的時間
Date endDate = new Date();
endDate.setTime(endDate.getTime()+6000L);
/**
* 建立一個Trigger例項,距離當前時間4秒鐘後執行任務,之後每隔兩秒執行一次任務,距離當前6秒之後停止執行
* withRepeatCount方法引數:SimpleTrigger.REPEAT_INDEFINITELY永遠執行下去,若設定為具體數字則就執行幾次
* 任務只執行兩次,由此可見endDate條件是優先於withRepeatCount
*/
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").startAt(startTime).endAt(endDate).
withSchedule(SimpleScheduleBuilder.simpleSchedule().
withIntervalInSeconds(2).withRepeatCount(5)).build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
注意:重複次數(withRepeatCount)可以為0、正整數或者是SimpleTrigger.REPEAT_INDEFINITELY常量值;重複的執行間隔必須為0或者長整數;一旦被制定了endTime引數,那麼它會覆蓋重複次數引數的效果。
3.淺談CronTrigger
CornTrigger:基於日曆的作業排程器,而不是像SimpleTrigger那樣精確指定間隔時間,比SimpleTrigger更常用。基於Cron表示式,用於配置CronTrigger例項,是由7個子表示式組成的字串,描述了時間表的詳細資訊。格式: [秒] [分] [小時][日] [月] [周] [年],示例程式碼如下:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//每秒鐘觸發一次任務
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").
withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ? *")).
build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
scheduler.scheduleJob(jobDetail,trigger);
}
}
常用Corn表示式:
- 2017年內每天10點15分觸發一次:0 15 10 ? * * 2017
- 每天10點15分觸發:0 15 10 ? * *
- 每天下午的2點到2點59分執行(整點開始,每隔5分鐘觸發):0 0/5 14 * * ?
- 從週一到週五的每天上午10點15分觸發:0 15 10 ? * MON-FRI
- 每月第三週的星期五(6#3:6代表星期五,#代表第)10點15分開始觸發:0 15 10 ? 6#3
- 從2016年到2017年每月最後一週的星期五10點15分觸發:0 15 10 ? * 6L 2016-2017
- 每天14點整至14點59分55秒及18點整至18點59分55秒,每5秒觸發一次:0/5 * 14,18 * * ?
4.淺談Scheduler
Scheduler——工廠模式:所有的Scheduler例項應該由SchedulerFactory來建立,一般包含:StdSchedulerFactory、DirectSchedulerFactory(引數資訊需要在程式碼中維護故不常用)。StdSchedulerFactory使用一組引數來建立和初始化Quartz排程器,配置引數一般儲存在quartz.properties檔案中,呼叫getScheduler方法就能建立和初始化排程器物件。Scheduler的主要函式:Data scheduleJob(JobDetail jobDetail,Trigger trigger);返回最近一次任務將要執行的時間,程式碼如下:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//每天10點15分觸發:0 15 10 ? * *
//每天下午的2點到2點59分執行(整點開始,每隔5分鐘觸發):0 0/5 14 * * ?
//從週一到週五的每天上午10點15分觸發:0 15 10 ? * MON-FRI
//每月第三週的星期五(6#3:6代表星期五,#代表第)10點15分開始觸發:0 15 10 ? 6#3
//從2016年到2017年每月最後一週的星期五10點15分觸發:0 15 10 ? * 6L 2016-2017
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").
withSchedule(CronScheduleBuilder.cronSchedule("0 15 10 ? * *")).
build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
System.out.println("Schedule time is:"+sf.format(scheduler.scheduleJob(jobDetail,trigger)));
}
}
void start();——啟動Scheduler;void standby();——將Scheduler暫時掛起,可以用start()繼續執行任務;void shutDown()關閉Scheduler且不能被重啟;示例程式碼如下:
package com.luna.timer.quarts;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException, InterruptedException {
// 建立一個JobDetail例項與HelloJob類繫結
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob", "group1").build();
//列印當前時間
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("列印當前時間:"+sf.format(startTime));
//每秒鐘執行一次,Scheduler執行兩秒之後掛起,Scheduler掛起3秒之後重新啟動
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().
withIdentity("mtTrigger", "group1").
withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ?")).
build();
//建立scheduler例項
SchedulerFactory sFactory = new StdSchedulerFactory();
Scheduler scheduler = sFactory.getScheduler();
scheduler.start();
System.out.println("Schedule time is:"+sf.format(scheduler.scheduleJob(jobDetail,trigger)));
Thread.sleep(2000L);
scheduler.standby();
Thread.sleep(3000L);
scheduler.start();
/**
* shutDown()可以傳入一個Boolean型別的引數,若引數為true:表示等待所有正在執行的job執行完畢之後,再關閉scheduler
* 若引數為false,即和沒有傳入引數一樣,表示直接關閉scheduler,不管是否有Job正在執行
*/
scheduler.shutdown(); //關閉之後不可以重新開啟
Thread.sleep(5000L);
scheduler.start();//呼叫重新開啟丟擲異常:The Scheduler cannot be restarted after shutdown() has been called.
}
}
執行緒池屬性:threadCount——工作者執行緒的數目,最少為1,最大不超過100;threadPriority——設定執行緒池執行緒的優先順序,最小值為1,最大值為10,預設值為5;org.quartz.threadPool.class——org.quartz.simple.SimpleThreadPool;作業儲存設定——描述了在排程器例項的生命週期中,job和trigger資訊是如何被儲存的;外掛配置——滿足特定需求用到的Quartz外掛的配置。
5.Quartz實際應用
- Spring配置Quartz作業的兩種方式:MethodInvokingJobDetailFactoryBean、JobDetailFactoryBean。