三、Quartz中Scheduler的理解和使用
(一)、排程器是什麼?有什麼作用?
排程器(Scheduler)是Quartz框架的心臟,用來管理觸發器和Job,並保證Job能被觸發執行。程式設計師與框架內部之間的呼叫都是通過org.quartz.Scheduler介面來完成的。對於Scheduler介面的實現,其實只是核心排程(org.quartz.core.QuartzScheduler)的一個代理,對代理的方法進行呼叫時會傳遞到底層核心排程例項上。QuartzScheduler處於Quartz框架的根位置,驅動著整個Quartz框架。
(二)、建立排程器
Scheduler介面有兩個實現類,分別為StdScheduler(標準預設排程器)和RemoteScheduler(遠端排程器),接下來重點講述StdScheduler例項。
那麼如何建立排程器例項呢?大家可能立馬會想到通過new的方式顯式的建立StdScheduler例項。StdScheduler只提供了一個帶參構造方法,此構造需要傳遞QuartzScheduler和SchedulingContext兩個例項引數:
public StdScheduler(QuartzScheduler sched, SchedulingContext schedCtxt)
然而我們一般不使用構造方法去建立排程器,而是通過排程器工廠來建立。排程器工廠介面org.quartz.SchedulerFactory提供了兩種不同型別的工廠實現,分別是org.quartz.impl.DirectSchedulerFactoryh和org.quartz.impl.StdSchedulerFactory,下面我們分別講述:
(1)、使用DirectSchedulerFactory工廠建立
此工廠方式建立適用於想絕對控制Scheduler例項的場景,下面用最簡單的方式通過DirectSchedulerFactory建立一個例項:
public static void main(String[] args) {
try {
DirectSchedulerFactory schedulerFactory = DirectSchedulerFactory.getInstance();
// 表示以3個工作執行緒初始化工廠
schedulerFactory.createVolatileScheduler(3);
Scheduler scheduler = schedulerFactory.getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
建立步驟:
1、通過DirectSchedulerFactory的getInstance方法得到拿到例項
2、呼叫createXXX方法初始化工廠
3、呼叫工廠例項的getScheduler方法拿到排程器例項
可以看出,DirectSchedulerFactory是通過createXXX方法傳遞配置引數來初始化工廠,這種初始化方式是一種硬編碼,在工作中用到的情況會很少。
(2)、使用StdSchedulerFactory工廠建立
此工廠是依賴一系列的屬性來決定如何建立排程器例項的。
屬性提供的方式有三種:
1、通過java.util.Properties屬性例項
2、通過外部屬性檔案提供
3、通過有屬性檔案內容的 java.io.InputStream 檔案流提供
public static void main(String[] args) {
try {
StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
// 第一種方式 通過Properties屬性例項建立
Properties props = new Properties();
props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, "org.quartz.simpl.SimpleThreadPool");
props.put("org.quartz.threadPool.threadCount", 5);
schedulerFactory.initialize(props);
// 第二種方式 通過傳入檔名
// schedulerFactory.initialize("my.properties");
// 第三種方式 通過傳入包含屬性內容的檔案輸入流
// InputStream is = new FileInputStream(new File("my.properties"));
// schedulerFactory.initialize(is);
// 獲取排程器例項
Scheduler scheduler = schedulerFactory.getScheduler();
} catch (Exception e) {
e.printStackTrace();
}
}
- 第一種方式向工廠傳入了兩個屬性,分別是執行緒池的類名和執行緒池大小,這兩個屬性是必須的,因為工廠沒有給它們指定預設值。
- 第二種方式是通過定義一個外部屬性檔案,底層實現是:首先通過Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)獲取檔案流,然後使用Properties例項的load方法載入檔案流形成屬性例項,最後在通過initialize(props)初始化完成。
- 第三種方式就是直接使用Properties例項的load方法載入檔案流形成屬性例項,再在通過initialize(props)初始化完成。
StdSchedulerFactory工廠還提供了無引數的initialize()方法,此方法本質也是通過載入屬性檔案,initialize()方法總是能載入成功的,因為quartz的jar包中有預設的quartz.properties檔案,具體的載入步驟:
1、檢查系統屬性中是否設定了檔名,通過System.getProperty("org.quartz.properties")
2、如果沒有設定,使用預設的quartz.properties作為要載入的檔名
3、然後先從當前工作目錄中載入這個檔案,如果沒有找到,再從系統 classpath 下載入這個檔案
StdSchedulerFactory工廠還可以不主動呼叫initialize()方法進行初始化,而是直接使用StdSchedulerFactory的靜態方法getDefaultScheduler()拿到排程器。
(三)、管理排程器
通過上述方法拿到排程器例項以後,在排程的生命週期中可以做以下工作,例如:啟動排程器,設定排程器為standby模式,繼續或停止排程器。
(1)啟動Scheduler
當排程器初始化完成,並且Job和Trigger也註冊完成,此時就可以呼叫scheduler.start()啟動排程器了。start()方法一旦被呼叫,排程器就開始搜尋需要執行的Job。
(2)設定standby模式
設定Scheduler為standby模式會讓排程器暫停尋找Job去執行。
應用場景舉例:當需要重啟資料庫時可以先將排程器設定為standby模式,待資料庫啟動完成後再通過start()啟動排程器。
(3)停止排程器
呼叫shutdown()或shutdown(boolean waitForJobsToComplete)方法停止排程器。第二個方法表示等待所有正在執行的job執行完畢後才停止排程器。shutdown方法呼叫後,就不可以再呼叫start方法了,因為shutdown方法會銷燬Scheduler建立的所有資源(執行緒、資料庫連線等)。
一般情況下,排程器啟動後不需要做其他任何事情。
到此,排程器講述完畢,如果大家有什麼問題,請在下方留言,謝謝!
相關文章
- Quartz框架中的Schedulerquartz框架
- Quartz job scheduler 學習quartz
- Spring Boot 參考指南(Quartz Scheduler)Spring Bootquartz
- Spring Scheduler定時任務 + QuartzSpringquartz
- Reactor中的Thread和SchedulerReactthread
- Quartz原理解密quartz解密
- Quartz - Spring和Quartz的整合quartzSpring
- Quartz.Net系列(十六):Misfire策略在SimpleScheduler和CronScheduler中的使用quartz
- Spring中Quartz排程器的使用Springquartz
- 理解和使用SQL Server中的並行SQLServer並行
- Quartz 使用教程quartz
- dbms_scheduler package系列三Package
- javascript 中{}和[] 的理解JavaScript
- 深入理解 RxJava2:Scheduler(2)RxJava
- 正確理解和使用JAVA中的字串常量池Java字串
- promise的理解和使用Promise
- NSProxy的理解和使用
- Git的理解和使用Git
- 物件的使用處理,作用域的和ajax中this的理解物件
- 理解.NET中的CLR原理(三) (轉)
- Quartz 簡單使用quartz
- Vue中keep-alive的深入理解和使用VueKeep-Alive
- 全面學習ORACLE Scheduler特性(7)使用Events之Scheduler丟擲的EventsOracle
- 理解vue中的scope的使用Vue
- redis api的使用和理解RedisAPI
- 使用DBMS_JOB和DBMS_SCHEDULER建立、管理job示例
- go中Tag的理解與使用Go
- python 程式的使用和理解Python
- 淺談ASP.NET Core中IOC與DI的理解和使用ASP.NET
- 全面學習ORACLE Scheduler特性(12)使用Windows和Window GroupsOracleWindows
- 理解 TCP(三):連線的建立和釋放TCP
- Quartz.NET 2.x 文件翻譯 - Lesson 1:使用Quartzquartz
- iOS中copy和strong的個人理解iOS
- 深入理解Java中的反射機制和使用原理!詳細解析invoke方法的執行和使用Java反射
- javascript中的prototype和__proto__的理解JavaScript
- 使用oracle dbms_scheduler代替crontabOracle
- redis list 使用和理解Redis
- 深入理解JS中的物件(三):class 的工作原理JS物件