
概念: quartz 是一個基于JAVA的定時任務調度框架
案例:?
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency>JobDetail job = JobBuilder.newJob(SchedulerTs.class).withIdentity("job1", "group1").usingJobData("name", "zs").build();Date endDate = DateUtils.addMinutes(new Date(), 2);SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger", "triggerGroup").withSchedule(SimpleScheduleBuilder.simpleSchedule()// 任務執行間隔.withIntervalInSeconds(10)// 重復執行次數.withRepeatCount(10)).forJob(job).endAt(endDate).startNow().build();StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();Scheduler scheduler = stdSchedulerFactory.getScheduler();// 配置任務scheduler.scheduleJob(job, trigger);scheduler.start();
使用、上手難度: 簡單
效果已經實現了、那么這個是怎么實現的呢、很費解、所以花了一早上時間扒了扒源碼、解惑
首先介紹幾個關鍵的類:?
????????StdSchedulerFactory 調度工廠、Scheduler 調度工具(類)、QuartzSchedulerThread 任務執行線程、SchedulerRepository 單例的調度倉庫 、?JobDetail 任務job封裝接口、SimpleTrigger 觸發器
????????現在看著有點多、記不住. 藍色部分忽略、他只是建造者模式的應用、封裝了 很多屬性方法、SchedulerRepository?單例的調度倉庫 也可以忽略、他只是一個map 用來存放 調度類的,并且也能夠避免相同調度類的重復創建;
????????重頭戲: 找到切入點?StdSchedulerFactory 調度工廠 是如何獲取到 調度類?Scheduler 的,并且?Scheduler.start? 和?scheduleJob?方法做了什么,我認為看懂這兩塊,基本就算差不多了
????????創建?StdSchedulerFactory 對象,只是一個空對象,什么也沒有做、關鍵點在于StdSchedulerFactory 的 getScheduler? 方法, 我們先看源碼

????????到現在比較明了了. 主要工作在 initialize 方法 和 instantiate 方法做的,我們逐個分析
????????initialize 源碼.只粘貼關鍵代碼. 實際上他也只是做了文件解析、將文件中的配置信息交給Properties,然后將 配置信息交給 工廠類的屬性 cfg 對象.這個對象只是在properties 外面封裝了一層.本質還是一個properties、配置信息包含一些線程數、執行間隔啥的. 這個就是配置、具體不做討論

????????instantiate 源碼、這個方法做的 任務比較多、涉及到 QuartzSchedulerThread 類的創建和啟動、調度倉庫調度器的插入、前面的配置信息就是在這一步裝配到任務上的,廢話不多說、直接看源碼


????????現在又會有一個疑惑、一個線程執行一次就結束了、他怎么做到一直監聽到有新任務進來的呢? 關鍵在于 一個while 循環 和?sigLock 對象的?await 與 notifyAll 操作,下面圖放了 這個線程run方法的動作,?到現在已經明確?instantiate 執行完之后線程就是已經啟動的了


????????現在我們再去看看?StdSchedulerFactory 的?scheduleJob?方法做了啥,將當前任務 保存到了 triggersByKey?和 jobsByKey?中 ,然后?交給了 listener 和 plugs 監聽處理

????????最后一步、啟動 StdSchedulerFactory.start

????????通過 sigLock 的notifyAll 通知 quartzSchedulerThread 線程繼續執行.
????????自己實現的任務是在何時被調用的呢??QuartzSchedulerThread::run 來尋找答案

????????新建的shell 是一個線程、initialize 關鍵步驟,newJob


????????找到了、反射 實例話 job類、得到了我們寫好的對象
????????runThread(shell) 執行了 shell 線程,run方法做了什么 我們看下,job.execute 任務被執行了.
完美,我看到的是這樣如果有疏漏麻煩評論區指正,感激,結尾附上思維導圖、相對來說更加詳細

