Quartz原理解析


最近項目中好多地方都需要用到定時器,一開始用的是netty的hashWheel,后來發現刪除任務的時候不是很好刪除,於是就放棄了,然后選擇了Quartz。

  • hashWheel定時器和Quartz的區別:

1)Quartz將定時任務分為任務和觸發器,而hashWheel只有任務的概念

2)Quartz通過一個TreeSet對所有的觸發器進行管理,而hashWheel通過一個hash輪來對所有的任務進行管理

3)Quartzl能夠非常方便的刪除定時任務,而netty的hashWheel暫時沒有刪除任務的接口(除非自己實現一個hashWheel定時器)

4)Quartz有一個專門的調度線程對任務進行管理,任務執行有另外專門的線程池,而hashWheel用一個線程實現對任務的管理和任務的執行。

5)Quartz能夠通過序列化,將定時任務保存在數據庫,而hashWheel不能

總的來說,Quartz的功能相對強大,而hashWheel相對要輕量級一點。

 

  • Quartz定時器原理:

接下來就講講Quartz的原理。

1)首先任務調度器調度的時序大致如下所示:

在這里將幾個重要的類調用的過程以序列圖的形式展現出來,上半部分展現的是啟動過程,下半部分展現的是任務調度的過程。

步驟1.用戶首先需要生成一個調度器工廠SchedulerFactory,可以用下面的方式實現自己的定制化:

1 Properties properties=new Properties();    properties.put("org.quartz.threadPool.class","org.quartz.simpl.SimpleThreadPool");
2 properties.put("org.quartz.threadPool.threadCount","10");
3 SchedulerFactory sf=new StdSchedulerFactory(properties);
View Code

步驟2.然后通過getScheduler()方法從調度器工廠里得到調度器實例,首先查找有沒有這樣的調度器,沒有的話,就生成一個,有的話直接返回。所以得到的一般是單例,即默認的調度器。

步驟3.Scheduler有一個QuartzSchedulerThread(Thread的子類)屬性,在scheduler實例化的時候,實例化了一個對象,並用ThreadExecutor啟動該線程對象。該線程就是調度線程,主要任務就是不停的從JobStore中獲取即將被觸發的觸發器(默認30s調度一次)。在這個時候調度線程雖然啟動,但是處於pause狀態。

步驟4.接下來是任務調度的部分:

1 Scheduler scheduler=sf.getScheduler();
2 scheduler.addJobListener(new TaskListener());
3 scheduler.scheduleJob(jobDetail, simpleTrigger);
4 scheduler.start();
View Code

client通過scheduleJob()方法將任務和觸發器存儲在JobStore中,通過start()方法將QuartzSchedulerThread的pause狀態設為false,通知調度線程執行任務,此后調度線程不停的從JobStore中去取即將觸發的任務。

 

2)任務執行的時序如下所示:

上半部分展現的是任務執行之前准備工作的時序,下半部分展現的是任務執行的時序。

步驟1.調度線程首先去線程池中獲取可用的線程,如果沒有的話,就阻塞。

步驟2.從JobStore(從存儲介質中獲取觸發器,存儲介質可以是內存也可以是數據庫)獲取(接下來30s內的)觸發器,然后等待該觸發器觸發。

步驟3.調度線程創建一個JobRunShell(就是一個Runnable),然后從線程池中調用線程執行該任務。

接下來就是任務執行的時序:

步驟4.獲取trigger、JobDetail以及生成Job實例,然后執行job的execute接口函數。

 

3)持久化的任務的執行時序如下:

 

以上就是Quartz的基本工作流程。

 

我在使用的時候遇到的一些問題:

1.Quartz與Spring的整合-Quartz中的job如何自動注入spring容器托管的對象?

這個問題網上已經有解決方法,但是按照它的步驟執行之后還是不行,后來經過嘗試發現,在實現接口ApplicationContextAware的時候,需要將private ApplicationContext applicationContext;改成靜態的private static ApplicationContext applicationContext,

之后這個問題就得到完美解決了。

 

彩蛋:

1.Quartz中文開發文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM