Quartz-SimpleTrigger解读
文章目錄
- 概述
- 小例子
- 創建一個在某個時間點執行的 Trigger:
- 創建一個在某個時間點執行的 Trigger,并且隨后每 10 秒執行一次,執行 10 次
- 創建一個 Trigger,并且在 5 分鐘后執行一次
- 創建一個 Trigger,并且立即執行一次,以后每 5 分鐘執行一次,直到 22:00
- 創建一個 Trigger,并且在下一小時開始的時候執行一次,以后每兩小時執行一次,永久循環
- SimpleTrigger 的錯過觸發機制
- 示例
- 示例源碼
概述
SimpleTrigger 可以讓你在某個精確的時間執行一次 Job,或者在某個精確的時間執行之后在特定的時間間隔內重復執行。
例如,如果你想在 2015 年 1 月 13 日上午 11:23:54 時間點精確執行,或者在這個時間點執行完成后再執行 5 次,每次間隔 10 秒鐘。
從SimpleTrigger接口的實現類SimpleTriggerImpl的源碼中我們可以看到如下屬性:
開始時間、結束時間、重復次數、重復間隔時間等,這些屬性看起來都很直觀,其中只有結束時間需要花點時間來特殊說明一下。
-
重復次數可以是 0,正整數(int),或者是SimpleTrigger.REPEAT_INDEFINITELY 常量值。
-
重復間隔時間必須是 0 或者正長整數(long),并且單位是毫秒。注意,如果將重復間隔時間設置為0,可能會發生 Trigger 同時觸發(并發)的問題。
如果熟悉Quartz 的DateBuilder類 ,你可能會發現使用它基于開始時間(或結束時間)來計算觸發次數非常有用。結束時間屬性將覆蓋重復次數屬性。
這在某些情況下非常有用,例如當你在創建好一個 Trigger 后,設置在指定的時間內每 10 秒執行一次,如果設置了結束時間就不用去計算開始時間到結束時間之間到底需要執行多少次,你可以簡單的設置結束時間,并使用 REPEAT_INDEFINITELY 作為重復次數(你還可以簡單地寫一個足夠大的數字作為重復次數,只要這個數字大于在結束時間之前的實際執行次數即可)。
SimpleTrigger 實例可以使用 TriggerBuilder(基于 Trigger 的主要屬性) 或 SimpleScheduleBuilder (基于 SimpleTrigger 的特殊屬性) 創建。要使用 DSL 風格需要先進行靜態導入:
import static org.quartz.TriggerBuilder.*; import static org.quartz.SimpleScheduleBuilder.*; import static org.quartz.DateBuilder.*:小例子
我們來看幾個小例子:
創建一個在某個時間點執行的 Trigger:
SimpleTrigger trigger = (SimpleTrigger) newTrigger() .withIdentity("trigger1", "group1").startAt(myStartTime) // some Date .forJob("job1", "group1") // identify job with name, group strings.build();創建一個在某個時間點執行的 Trigger,并且隨后每 10 秒執行一次,執行 10 次
trigger = newTrigger().withIdentity("trigger3", "group1").startAt(myTimeToStartFiring) // if a start time is not given (if this line were omitted), "now" is implied.withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)) // note that 10 repeats will give a total of 11 firings.forJob(myJob) // identify job with handle to its JobDetail itself .build();創建一個 Trigger,并且在 5 分鐘后執行一次
trigger = (SimpleTrigger) newTrigger() .withIdentity("trigger5", "group1").startAt(futureDate(5, IntervalUnit.MINUTE)) // use DateBuilder to create a date in the future.forJob(myJobKey) // identify job with its JobKey.build();創建一個 Trigger,并且立即執行一次,以后每 5 分鐘執行一次,直到 22:00
trigger = newTrigger().withIdentity("trigger7", "group1").withSchedule(simpleSchedule().withIntervalInMinutes(5).repeatForever()).endAt(dateOf(22, 0, 0)).build();創建一個 Trigger,并且在下一小時開始的時候執行一次,以后每兩小時執行一次,永久循環
trigger = newTrigger().withIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group.startAt(evenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00")).withSchedule(simpleSchedule().withIntervalInHours(2).repeatForever())// note that in this example, 'forJob(..)' is not called // - which is valid if the trigger is passed to the scheduler along with the job .build();scheduler.scheduleJob(trigger, job);花點時間研究所有 TriggerBuilder 和 SimpleScheduleBuilder 中的方法,你將更加熟悉如何使用,這些方法有很多都沒有在上面的例子中出現。
注意,TriggerBuilder(或者 Quartz 的其它 Builder)在你沒有顯式的設置屬性的時候會設置一個合理的默認屬性。例如,如果你沒有調用 withIdentity(…) 方法,那么 TriggerBuilder 將會為你的 Trigger 設置一個默認名稱;如果沒有調用 startAt(…) 方法,那么當前時間將會作為開始時間。
SimpleTrigger 的錯過觸發機制
當 Quartz 發生錯過觸發事件后,SimpleTrigger 提供了幾個機制,這些機制以常量形式保存在 SimpleTrigger 中.
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY MISFIRE_INSTRUCTION_FIRE_NOW MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT其中 Trigger.MISFIRE_INSTRUCTION_SMART_POLICY (智能策略)是所有 Trigger 的默認值。
當創建 SimpleTrigger 的時候,可以通過 SimpleSchedulerBuilder 指定錯過觸發機制:
trigger = newTrigger().withIdentity("trigger7", "group1").withSchedule(simpleSchedule().withIntervalInMinutes(5).repeatForever().withMisfireHandlingInstructionNextWithExistingCount()).build();示例
package com.xgj.quartz.quartzItself.simpleTriggerDemo;import java.util.Date;import org.apache.log4j.Logger; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey;public class SimpleJob implements Job {private static Logger _log = Logger.getLogger(SimpleJob.class);/*** Empty constructor for job initialization*/public SimpleJob() {}/*** <p>* Called by the <code>{@link org.quartz.Scheduler}</code> when a* <code>{@link org.quartz.Trigger}</code> fires that is associated with the* <code>Job</code>.* </p>* * @throws JobExecutionException* if there is an exception while executing the job.*/public void execute(JobExecutionContext context)throws JobExecutionException {// This job simply prints out its job name and the// date and time that it is runningJobKey jobKey = context.getJobDetail().getKey();_log.info("SimpleJob says: " + jobKey + " executing at " + new Date());} } package com.xgj.quartz.quartzItself.simpleTriggerDemo;import static org.quartz.DateBuilder.futureDate; import static org.quartz.JobBuilder.newJob; import static org.quartz.JobKey.jobKey; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger;import java.util.Date;import org.apache.log4j.Logger; import org.quartz.DateBuilder; import org.quartz.DateBuilder.IntervalUnit; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.SchedulerMetaData; import org.quartz.SimpleTrigger; import org.quartz.impl.StdSchedulerFactory;import com.xgj.quartz.quartzItself.quickDemo.SimpleJob;/*** * * @ClassName: SimpleTriggerExample* * @Description: This Example will demonstrate all of the basics of scheduling* capabilities of Quartz using Simple Triggers.* * @author: Mr.Yang* * @date: 2017年10月7日 下午8:49:43*/ public class SimpleTriggerExample {public void run() throws Exception {Logger log = Logger.getLogger(SimpleTriggerExample.class);log.info("------- Initializing -------------------");// First we must get a reference to a schedulerSchedulerFactory sf = new StdSchedulerFactory();Scheduler sched = sf.getScheduler();log.info("------- Initialization Complete --------");log.info("------- Scheduling Jobs ----------------");// jobs can be scheduled before sched.start() has been called// get a "nice round" time a few seconds in the future...Date startTime = DateBuilder.nextGivenSecondDate(null, 15);// job1 will only fire once at date/time "ts"JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build();SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger1", "group1").startAt(startTime).build();// schedule it to run!Date ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// job2 will only fire once at date/time "ts"job = newJob(SimpleJob.class).withIdentity("job2", "group1").build();trigger = (SimpleTrigger) newTrigger().withIdentity("trigger2", "group1").startAt(startTime).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// job3 will run 11 times (run once and repeat 10 more times)// job3 will repeat every 10 secondsjob = newJob(SimpleJob.class).withIdentity("job3", "group1").build();trigger = newTrigger().withIdentity("trigger3", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// the same job (job3) will be scheduled by a another trigger// this time will only repeat twice at a 70 second intervaltrigger = newTrigger().withIdentity("trigger3", "group2").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(2)).forJob(job).build();ft = sched.scheduleJob(trigger);log.info(job.getKey() + " will [also] run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// job4 will run 6 times (run once and repeat 5 more times)// job4 will repeat every 10 secondsjob = newJob(SimpleJob.class).withIdentity("job4", "group1").build();trigger = newTrigger().withIdentity("trigger4", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(5)).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// job5 will run once, five minutes in the futurejob = newJob(SimpleJob.class).withIdentity("job5", "group1").build();trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1").startAt(futureDate(5, IntervalUnit.MINUTE)).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// job6 will run indefinitely, every 40 secondsjob = newJob(SimpleJob.class).withIdentity("job6", "group1").build();trigger = newTrigger().withIdentity("trigger6", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInSeconds(40).repeatForever()).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");log.info("------- Starting Scheduler ----------------");// All of the jobs have been added to the scheduler, but none of the// jobs// will run until the scheduler has been startedsched.start();log.info("------- Started Scheduler -----------------");// jobs can also be scheduled after start() has been called...// job7 will repeat 20 times, repeat every five minutesjob = newJob(SimpleJob.class).withIdentity("job7", "group1").build();trigger = newTrigger().withIdentity("trigger7", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20)).build();ft = sched.scheduleJob(job, trigger);log.info(job.getKey() + " will run at: " + ft + " and repeat: "+ trigger.getRepeatCount() + " times, every "+ trigger.getRepeatInterval() / 1000 + " seconds");// jobs can be fired directly... (rather than waiting for a trigger)job = newJob(SimpleJob.class).withIdentity("job8", "group1").storeDurably().build();sched.addJob(job, true);log.info("'Manually' triggering job8...");sched.triggerJob(jobKey("job8", "group1"));log.info("------- Waiting 30 seconds... --------------");try {// wait 33 seconds to show jobsThread.sleep(30L * 1000L);// executing...} catch (Exception e) {//}// jobs can be re-scheduled...// job 7 will run immediately and repeat 10 times for every secondlog.info("------- Rescheduling... --------------------");trigger = newTrigger().withIdentity("trigger7", "group1").startAt(startTime).withSchedule(simpleSchedule().withIntervalInMinutes(5).withRepeatCount(20)).build();ft = sched.rescheduleJob(trigger.getKey(), trigger);log.info("job7 rescheduled to run at: " + ft);log.info("------- Waiting five minutes... ------------");try {// wait five minutes to show jobsThread.sleep(300L * 1000L);// executing...} catch (Exception e) {//}log.info("------- Shutting Down ---------------------");sched.shutdown(true);log.info("------- Shutdown Complete -----------------");// display some stats about the schedule that just ranSchedulerMetaData metaData = sched.getMetaData();log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");}public static void main(String[] args) throws Exception {SimpleTriggerExample example = new SimpleTriggerExample();example.run();} }示例源碼
代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster
總結
以上是生活随笔為你收集整理的Quartz-SimpleTrigger解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Quartz-Trigger详解
- 下一篇: Quartz-任务调度信息持久化到DB中