定时器启动

上图通过spring加载quartz

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
...
</bean>

SpringContext在加载SchedulerFactoryBean时会去加载他的afterPropertiesSet方法,而SchedulerFactoryBean会去与quartz的StdSchedulerFactory交互初使化配置,StdSchedulerFactory会create类QuartzScheduler,
QuartzScheduler会启动总控制线程QuartzSchedulerThread不停的轮循。

类目结构如下

1、StdSchedulerFactory是工厂类,还有一个工厂类DirectSchedulerFactory比较简单,而StdSchedulerFactory是可以加载各种属性的。属性的加载initialize方法,Contants里面都是参数,可以按说明在quartz.properties上加。

2、StdSchedule只是QuartzSchedule的一个包装类,方法更清晰。

3、QuartzScheduler是整个定时任务框架工作的核心类,上面的类图仅仅展现了QuartzScheduler中几个核心成员。

4、QuartzSchedulerResources可以认为是存放一切配置以及通过配置初始化出来的一些资源的容器,其中包括了存储job定义的jobStore

5、JobStore可以有多种实现,我们使用的是默认的RAMJobStore;

6、ThreadPool,还有一个非常重要的对象就是ThreadPool,这个线程池管理着执行我们定义的Job所需的所有线程。这个线程池的大小配置就是通过我上面提到过的“org.quartz.threadPool.threadCount”进行配置的。

QuartzScheduler另一个重要成员就是QuartzSchedulerThread,没有这个线程的话我们所有定义的任务都不会被触发执行,也就是说它是Quartz后台的“守护线程”,它不断的去查找合适的job并触发这些Job执行。

StdSchedulerFactory.getSchedule只是启动了QuartzSchedulerThread线程,开关未打开。
Scheduler.start()才是打开QuartzSchedulerThread的开关,真正开始线程轮循。
当总线程QuartzSchedulerThread处理完了数据库对TRIGGER操作后,就开始把任务放到线程中执行了。

QuartzSchedulerThread轮询流程

quartz运行时由QuartzSchedulerThread类作为主体,循环执行调度流程。JobStore作为中间层,按照quartz的并发策略执行数据库操作,完成主要的调度逻辑。JobRunShellFactory负责实例化JobDetail对象,将其放入线程池运行。LockHandler负责获取LOCKS表中的数据库锁。

处理流程

第一部分:获取trigger

1、通知JobStore获取待触发的TRIGGER
2、JobStore获取数据库锁(获取TRIGGER),获取trigger_access的行级锁
3、JobStore获取30s内触发且状态为waiting的TRIGGER
4、获取这些TRIGGER关联的job信息
5、将这些TRIGGER的状态置为acquired
6、将待触发的TRIGGER插入表中QRTZ_FIRED_TRIGGERS
7、提交获取TRIGGER的事务,行级锁被释放
8、返回待触发的TRIGGER列表

第二部分:触发trigger

10、通知JobStore触发TRIGGER
11、JobStore获取数据库锁(触发)TRIGGER,获取stat_access行级锁
12、JobStore确认TRIGGER状态
13、读取job信息
14、读取TRIGGER的calendar信息
15、更新TRIGGER的信息至executing
16、根据信息,更新TRIGGER状态至阻塞、终结、等待等状态
17、持久化TRIGGER,更新下次触发时间等
18、提交触发TRIGGER的事务,行级锁被释放
19、返回待执行的jobDetail对象

第三部分:实例化并执行Job

根据待执行的jobDetail列表,实例化job,并将其放入线程池中运行

可以看到,这个过程中有两个相似的过程:同样是对数据表的更新操作,同样是在执行操作前获取锁 操作完成后释放锁.这一规则可以看做是quartz解决集群问题的核心思想。
一个调度器实例在执行涉及到分布式问题的数据库操作前,首先要获取QUARTZ2_LOCKS表中对应当前调度器的行级锁,获取锁后即可执行其他表中的数据库操作,随着操作事务的提交,行级锁被释放,供其他调度器实例获取。
集群中的每一个调度器实例都遵循这样一种严格的操作规程,那么对于同一类调度器来说,每个实例对数据库的操作只能是串行的.而不同名的调度器之间却可以并行执行。

参考链接:http://www.cnblogs.com/davidwang456/p/4205237.html

其他参考:http://www.cnblogs.com/surprizeFuture/articles/4564293.html

quartz(7)-源码分析的更多相关文章

  1. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  2. 定时组件quartz系列<三>quartz调度机制调研及源码分析

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  3. (1)quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...

  4. Quartz源码分析

    先简单介绍一下quartz,Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统.quartz可用于创建执行数十,数百甚至数十 ...

  5. quartz源码分析——执行引擎和线程模型

    title: quartz源码分析--执行引擎和线程模型 date: 2017-09-09 23:14:48 categories: quartz tags: [quartz, 源码分析] --- - ...

  6. Quartz源码——QuartzSchedulerThread.run() 源码分析(三)

    QuartzSchedulerThread.run()是主要处理任务的方法!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析 ...

  7. Quartz源码——scheduler.start()启动源码分析(二)

    scheduler.start()是Quartz的启动方式!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! Quar ...

  8. Quartz源码——JobStore保存JonDetail和Trigger源码分析(一)

    我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! {0} :表的前缀 ,如表qrtz_trigger ,{0}== qrtz_ {1}:quartz ...

  9. [源码分析] 定时任务调度框架 Quartz 之 故障切换

    [源码分析] 定时任务调度框架 Quartz 之 故障切换 目录 [源码分析] 定时任务调度框架 Quartz 之 故障切换 0x00 摘要 0x01 基础概念 1.1 分布式 1.1.1 功能方面 ...

随机推荐

  1. 编写高质量代码–改善python程序的建议(五)

    原文发表在我的博客主页,转载请注明出处! 建议二十三:遵循异常处理的几点基本原则 python中常用的异常处理语法是try.except.else.finally,它们可以有多种组合,语法形式如下: ...

  2. 巨蟒python全栈开发-第9天 初识函数

    一.今日主要内容总览(重点) 1.什么是函数? f(x)=x+1 y=x+1 函数是对功能或者动作的封装2.函数的语法和定义 def 函数名(): 函数体 调用:函数名()3.关于函数的返回值 ret ...

  3. js事件委托和jQuery事件绑定on , off , one , bind , unbind , die

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  4. Java 之 GUI 编程

    GUI (Graphical User Interface, 图形用户接口) CLI (Command line User Interface, 命令行用户接口) Java 为 GUI 提供的对象都存 ...

  5. python线程间数据共享(示例演示)

    ``` import threading data_list = [] def task(arg): data_list.append(arg) print(data_list) def run(): ...

  6. Github的markdwon如何使用表情符(Emoji)?表情包大全

    如输入 :smile: 会输出  

  7. java-序列化-001-原生介绍

    一.什么是对象序列化 java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长.但在现实应用中, ...

  8. 用仿ActionScript的语法来编写html5——第二篇,利用Sprite来实现动画

    上一篇,我已经模仿as,加入了LBitmap和LBitmapData类,并且用它们实现了静态图片的显示.这次用Sprite来动态显示图片.依然遵循上一篇对显示对象的处理的思路,添加LSprite类,并 ...

  9. 测试Windows live Writer

    private String GetRandomint(int codeCount) { Random random = new Random(); string min = "" ...

  10. 第七课 GDB调试 (下)

    1序言: 通过前面一节第六课 GDB调试 (下)文章,可以掌握理解了gdb调试:怎么启动.运行,打断点.查看变量.甚至改变变量等的知识,今天来大概讲解下调试bug的类型. 2知识点: 2.1 就像之前 ...