quartz源码分析(四)
Quartz 核心部分是quartz的scheduler运行
1、首先看下quartz的一个实例的运行流程图:
????????????
Scheduler的基本执行过程如上图所示,但是具体的实现确各有个的不同,如第一章所讲的也是一种实现,当然只是最简单的实现,下面就结合quartz框架提供的一个实际的例子,讲解scheduler的标准stdscheduler的执行过程。
先看看本部分涉及的一些类的简单关系
?
最主要的类是QuartzSchedulerThread,他承载了所有运行环境中所有需要的参数,并所有的运行方法都是在更改QuartzSchedulerThread的变量,从而来控制线程运行方法run的执行流程。Resources仅仅是资源类,存储基本的资源,signaler类是信号量类,控制run的执行过程。QuartzScheduler是StdScheduler的代理,他直接除了scheduler的所有操作。Thread的中采用一个final类型的sigLock做为信号量,并使用halt和paused表示线程的终止和暂停。
1、先创建Schedulerfactory。使用SchedulerFactory的实现类StdSchedulerFactory创建一个SchedulerFactory实例。在创建factory之初,jvm不实例化任何成员变量,仅仅是一个空的构造方法。
2、获取scheduler。通过schedulerfactory获取scheduler。获取scheduler需要一系列的参数,这些参数是配置在名为quartz.properties的文件之中。先从系统中(即System.getProperties)获取名为org.quartz.properties的变量值,如果不存在,默认为quartz.properties,从当前的运行环境找名称为quartz.properties的属性文件加载,还是不存在,则去当前类加载器目录,也就是classpath中加载。然后把系统的属性同样加载到properties,最后构造quartz特有的属性对象。
?
3、jobdetail和trigger的创建过程很简单,以上已经提及,在此简述过程图:
????????
4、当scheduler实例化后,并且jobdetail和trigger已经实例化,下面就开始scheduler任务了。Scheduler的过程:
1)先从stdscheduler中获取QuartzScheduler,Stdscheduler是QuartzScheduler的代理,所有方法sheduler的方法的实际运行都在QuartzScheduler中。
2)scheduler前检查:检查scheduler的状态,jobdetail和trigger等是否为空
3)store job。先对jobdetail做clone,判断现存的jobkey列表中是否存在,如果存在,异常。如果不存在,把jobdetail分别为group和key存储在内存中。
4)store trigger。先对trigger做clone,判断triggerkey列表中是否存在。如果存在使用removetrigger移除,不过此方法有明显BUG,并且一般不会使用,在此不做赘述。把trigger添加到arraylist中,把trigger分别为group和key存储在内存中。再判断trigger不是被暂停状态时,添加到treeset中。
5)notify scheduler监听器job被添加。
6)通知。之前没说的一个重要点,在这里用上了。QuartzSchedulerThread,这个thread线程类是在QuartzScheduler对象创建的时候手工建立起来的,只是对多线程进行一个支持。线程Thread在穿件过程中几个非常重要的变量是,halted=new AtmicBoolean(false);用来原子判断线程的状态,另外线程中的一个重要的信号量为final Object sigLock = new Object(),此对象控制了线程的wait和notify函数。QuartzSchedulerThread在QuartzScheduler在创建的的时候,就已经运行线程启动方法运行,只是此时的paused状态为true,表示目前线程是暂停状态。
随后更新当前调用trigger的下次运行时间并复制给signaledNextFireTime,然后通知schedulerThread去重新分配调用任务。
7)notify scheduler监听器trigger被添加。
此步骤的任务执行过程为:
?
5、scheduler start:此不只是通过代理的更改模式更新QuartzSchedulerThread的paused的值为false,使得线程的run方法可以去执行job任务。
6、scheduler shutdown 关闭scheduler的相关资源,并把非守护线程退出。
至此,quartz分析结束。