Quartz原理解析

Quartz原理解析

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

  • hashWheel定時器和Quartz的區別:

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

2)Quartz經過一個TreeSet對全部的觸發器進行管理,而hashWheel經過一個hash輪來對全部的任務進行管理數據庫

3)Quartzl可以很是方便的刪除定時任務,而netty的hashWheel暫時沒有刪除任務的接口(除非本身實現一個hashWheel定時器)app

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

5)Quartz可以經過序列化,將定時任務保存在數據庫,而hashWheel不能post

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

 

  • Quartz定時器原理:

接下來就講講Quartz的原理。線程

1)首先任務調度器調度的時序大體以下所示:3d

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

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

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

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,

以後這個問題就獲得完美解決了。

相關文章
相關標籤/搜索