Quartz中Triggers介紹

2018-09-12 10:53 更新

job一樣,trigger也很容易使用,但是還有一些擴(kuò)展選項(xiàng)需要理解,以便更好地使用quartz。trigger也有很多類型,我們可以根據(jù)實(shí)際需要來選擇。

最常用的兩種trigger會(huì)分別在第5課:SimpleTrigger和第6課:CronTrigger中講到。

Trigger的公共屬性

所有類型的trigger都有TriggerKey這個(gè)屬性,表示trigger的身份;除此之外,trigger還有很多其它的公共屬性。這些屬性,在構(gòu)建trigger的時(shí)候可以通過TriggerBuilder設(shè)置。

trigger的公共屬性有:

  • jobKey屬性:當(dāng)trigger觸發(fā)時(shí)被執(zhí)行的job的身份;
  • startTime屬性:設(shè)置trigger第一次觸發(fā)的時(shí)間;該屬性的值是java.util.Date類型,表示某個(gè)指定的時(shí)間點(diǎn);有些類型的trigger,會(huì)在設(shè)置的startTime時(shí)立即觸發(fā),有些類型的trigger,表示其觸發(fā)是在startTime之后開始生效。比如,現(xiàn)在是1月份,你設(shè)置了一個(gè)trigger–“在每個(gè)月的第5天執(zhí)行”,然后你將startTime屬性設(shè)置為4月1號(hào),則該trigger第一次觸發(fā)會(huì)是在幾個(gè)月以后了(即4月5號(hào))。
  • endTime屬性:表示trigger失效的時(shí)間點(diǎn)。比如,”每月第5天執(zhí)行”的trigger,如果其endTime是7月1號(hào),則其最后一次執(zhí)行時(shí)間是6月5號(hào)。

其它的屬性,會(huì)在下文中解釋。

優(yōu)先級(jí)(priority)

如果你的trigger很多(或者Quartz線程池的工作線程太少),Quartz可能沒有足夠的資源同時(shí)觸發(fā)所有的trigger;這種情況下,你可能希望控制哪些trigger優(yōu)先使用Quartz的工作線程,要達(dá)到該目的,可以在trigger上設(shè)置priority屬性。比如,你有N個(gè)trigger需要同時(shí)觸發(fā),但只有Z個(gè)工作線程,優(yōu)先級(jí)最高的Z個(gè)trigger會(huì)被首先觸發(fā)。如果沒有為trigger設(shè)置優(yōu)先級(jí),trigger使用默認(rèn)優(yōu)先級(jí),值為5;priority屬性的值可以是任意整數(shù),正數(shù)、負(fù)數(shù)都可以。

注意:只有同時(shí)觸發(fā)的trigger之間才會(huì)比較優(yōu)先級(jí)。10:59觸發(fā)的trigger總是在11:00觸發(fā)的trigger之前執(zhí)行。

注意:如果trigger是可恢復(fù)的,在恢復(fù)后再調(diào)度時(shí),優(yōu)先級(jí)與原trigger是一樣的。

錯(cuò)過觸發(fā)(misfire Instructions)

trigger還有一個(gè)重要的屬性misfire;如果scheduler關(guān)閉了,或者Quartz線程池中沒有可用的線程來執(zhí)行job,此時(shí)持久性的trigger就會(huì)錯(cuò)過(miss)其觸發(fā)時(shí)間,即錯(cuò)過觸發(fā)(misfire)。不同類型的trigger,有不同的misfire機(jī)制。它們默認(rèn)都使用“智能機(jī)制(smart policy)”,即根據(jù)trigger的類型和配置動(dòng)態(tài)調(diào)整行為。當(dāng)scheduler啟動(dòng)的時(shí)候,查詢所有錯(cuò)過觸發(fā)(misfire)的持久性trigger。然后根據(jù)它們各自的misfire機(jī)制更新trigger的信息。當(dāng)你在項(xiàng)目中使用Quartz時(shí),你應(yīng)該對(duì)各種類型的trigger的misfire機(jī)制都比較熟悉,這些misfire機(jī)制在JavaDoc中有說明。關(guān)于misfire機(jī)制的細(xì)節(jié),會(huì)在講到具體的trigger時(shí)作介紹。

日歷示例(calendar)

Quartz的Calendar對(duì)象(不是java.util.Calendar對(duì)象)可以在定義和存儲(chǔ)trigger的時(shí)候與trigger進(jìn)行關(guān)聯(lián)。Calendar用于從trigger的調(diào)度計(jì)劃中排除時(shí)間段。比如,可以創(chuàng)建一個(gè)trigger,每個(gè)工作日的上午9:30執(zhí)行,然后增加一個(gè)Calendar,排除掉所有的商業(yè)節(jié)日。

任何實(shí)現(xiàn)了Calendar接口的可序列化對(duì)象都可以作為Calendar對(duì)象,Calendar接口如下:


package org.quartz;

public interface Calendar {

  public boolean isTimeIncluded(long timeStamp);

  public long getNextIncludedTime(long timeStamp);

}

注意到這些方法的參數(shù)類型為long。你也許猜到了,他們就是毫秒單位的時(shí)間戳。即Calendar排除時(shí)間段的單位可以精確到毫秒。你也許對(duì)“排除一整天”的Calendar比較感興趣。Quartz提供的org.quartz.impl.HolidayCalendar類可以很方便地實(shí)現(xiàn)。

Calendar必須先實(shí)例化,然后通過addCalendar()方法注冊(cè)到scheduler。如果使用HolidayCalendar,實(shí)例化后,需要調(diào)用addExcludedDate(Date date)方法從調(diào)度計(jì)劃中排除時(shí)間段。以下示例是將同一個(gè)Calendar實(shí)例用于多個(gè)trigger:

HolidayCalendar cal = new HolidayCalendar();
cal.addExcludedDate( someDate );
cal.addExcludedDate( someOtherDate );

sched.addCalendar("myHolidays", cal, false);


Trigger t = newTrigger()
    .withIdentity("myTrigger")
    .forJob("myJob")
    .withSchedule(dailyAtHourAndMinute(9, 30)) // execute job daily at 9:30
    .modifiedByCalendar("myHolidays") // but not on holidays
    .build();

// .. schedule job with trigger

Trigger t2 = newTrigger()
    .withIdentity("myTrigger2")
    .forJob("myJob2")
    .withSchedule(dailyAtHourAndMinute(11, 30)) // execute job daily at 11:30
    .modifiedByCalendar("myHolidays") // but not on holidays
    .build();

// .. schedule job with trigger2

接下來的幾個(gè)課程將介紹觸發(fā)器的施工/建造細(xì)節(jié)。現(xiàn)在,只要認(rèn)為上面的代碼創(chuàng)建了兩個(gè)觸發(fā)器,每個(gè)觸發(fā)器都計(jì)劃每天觸發(fā)。然而,在日歷所排除的期間內(nèi)發(fā)生的任何發(fā)射都將被跳過。

請(qǐng)參閱org.quartz.impl.calendar包,了解適合您需要的多個(gè)Calendar實(shí)現(xiàn)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)