閱讀540 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Quartz教程五:SimpleTrigger

本係列教程由quartz-2.2.x官方文檔翻譯、整理而來,希望給同樣對quartz感興趣的朋友一些參考和幫助,有任何不當或錯誤之處,歡迎指正;有興趣研究源碼的同學,可以參考我對quartz-core源碼的注釋(進行中)

SimpleTrigger可以滿足的調度需求是:在具體的時間點執行一次,或者在具體的時間點執行,並且以指定的間隔重複執行若幹次。比如,你有一個trigger,你可以設置它在2015年1月13日的上午11:23:54準時觸發,或者在這個時間點觸發,並且每隔2秒觸發一次,一共重複5次。

根據描述,你可能已經發現了,SimpleTrigger的屬性包括:開始時間、結束時間、重複次數以及重複的間隔。這些屬性的含義與你所期望的是一致的,隻是關於結束時間有一些地方需要注意。

重複次數,可以是0、正整數,以及常量SimpleTrigger.REPEAT_INDEFINITELY。重複的間隔,必須是0,或者long型的正數,表示毫秒。注意,如果重複間隔為0,trigger將會以重複次數並發執行(或者以scheduler可以處理的近似並發數)。

如果你還不熟悉DateBuilder,了解後你會發現使用它可以非常方便地構造基於開始時間(或終止時間)的調度策略。

endTime屬性的值會覆蓋設置重複次數的屬性值;比如,你可以創建一個trigger,在終止時間之前每隔10秒執行一次,你不需要去計算在開始時間和終止時間之間的重複次數,隻需要設置終止時間並將重複次數設置為REPEAT_INDEFINITELY(當然,你也可以將重複次數設置為一個很大的值,並保證該值比trigger在終止時間之前實際觸發的次數要大即可)。

SimpleTrigger實例通過TriggerBuilder設置主要的屬性,通過SimpleScheduleBuilder設置與SimpleTrigger相關的屬性。要使用這些builder的靜態方法,需要靜態導入:

import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.DateBuilder.*:

下麵的例子,是基於簡單調度(simple schedule)創建的trigger。建議都看一下,因為每個例子都包含一個不同的實現點:

指定時間開始觸發,不重複:

    SimpleTrigger trigger = (SimpleTrigger) newTrigger() 
        .withIdentity("trigger1", "group1")
        .startAt(myStartTime)                     // some Date 
        .forJob("job1", "group1")                 // identify job with name, group strings
        .build();

指定時間觸發,每隔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();

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();

立即觸發,每個5分鍾執行一次,直到22:00:

    trigger = newTrigger()
        .withIdentity("trigger7", "group1")
        .withSchedule(simpleSchedule()
            .withIntervalInMinutes(5)
            .repeatForever())
        .endAt(dateOf(22, 0, 0))
        .build();

在下一小時整點觸發,每個2小時執行一次,一直重複:

    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);

請查閱TriggerBuilderSimpleScheduleBuilder提供的方法,以便對上述示例中未提到的選項有所了解。

TriggerBuilder(以及Quartz的其它builder)會為那些沒有被顯式設置的屬性選擇合理的默認值。比如:如果你沒有調用withIdentity(..)方法,TriggerBuilder會為trigger生成一個隨機的名稱;如果沒有調用startAt(..)方法,則默認使用當前時間,即trigger立即生效。

SimpleTrigger Misfire策略

SimpleTrigger有幾個misfire相關的策略,告訴quartz當misfire發生的時候應該如何處理。(Misfire策略參考教程四:Trigger介紹)。這些策略以常量的形式在SimpleTrigger中定義(JavaDoc中介紹了它們的功能)。這些策略包括:

SimpleTrigger的Misfire策略常量:

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都有一個Trigger.MISFIRE_INSTRUCTION_SMART_POLICY策略可以使用,該策略也是所有trigger的默認策略。

如果使用smart policy,SimpleTrigger會根據實例的配置及狀態,在所有MISFIRE策略中動態選擇一種Misfire策略。SimpleTrigger.updateAfterMisfire()的JavaDoc中解釋了該動態行為的具體細節。

在使用SimpleTrigger構造trigger時,misfire策略作為基本調度(simple schedule)的一部分進行配置(通過SimpleSchedulerBuilder設置):

    trigger = newTrigger()
        .withIdentity("trigger7", "group1")
        .withSchedule(simpleSchedule()
            .withIntervalInMinutes(5)
            .repeatForever()
            .withMisfireHandlingInstructionNextWithExistingCount())
        .build();

最後更新:2017-05-23 16:32:44

  上一篇:go  演講實錄丨季向陽 無人係統智能傳感與計算
  下一篇:go  Java設計模式:裝飾者模式