
 
概念: 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 任务被执行了.
 
完美,我看到的是这样如果有疏漏麻烦评论区指正,感激,结尾附上思维导图、相对来说更加详细
 

 
