前序:
做为企业里的任务调度框架,出现同一时间点同时运行两个任务,或者两个任务因为开始的执行时间和执行时间的长短,很有可能出现任务并发执行的情况;因为Quartz的实现是采用java编程,那么多线程机制就是解决并发问题的必要手段了;
线程与 Quartz 来说尤为重要,因为 Quartz 就是设计为支持同时运行多个 Job。为达到此效果,Quartz 非常倚重于内建于 Java 语言的线程,借助于自己的类和借口还有所增强。
当 Quartz Schduler 首次由某个工厂方法创建时,工厂配置了 Scheduler 会在它的整个生命周期中用到的几个重要的资源。其中一些重要的资源是与线程相关的。提醒下大家,常见的Schduler工厂类为DirectoSchedulerFactory 和StdSchedulerFactory;
1.主处理线程:QuartzSchedulerThread
Quartz 应用第一次运行时,main 线程会启动 Scheduler。QuartzScheduler 被创建并创建一个 org.quartz.core.QuartzSchedulerThread 类的实例。QuartzSchedulerThread 包含有决定何时下一个 Job 将被触发的处理循环。顾名思义,QuartzSchedulerThread 是一个 Java 线程。它作为一个非守护线程运行在正常优先级下。为了更好的解释上面的这段话,我们可以将QuartzSchedulerThread 对应的线程看成一个main线程,而没有由触发器触发的任务,看成该main方法里所创建的若干线程;
QuartzSchedulerThread 的主处理循环的职责描述如下:
1. 当 Scheduler 正在运行时:
A. 检查是否有转换为 standby 模式的请求。
1. 假如 standby 方法被调用,等待继续的信号
B. 询问 JobStore 下次要被触发的 Trigger.
JobStore:要使 Job 存储在内存中需通过设置org.quartz.jobStrore.class 属性为 org.quartz.simpl.RAMJobStore。假如我们不希望在 JVM 退出之后丢失调度器的状态信息的话,我们可以使用关系型数据库来存储这些信息。这需要另一个作业存储实现(JobStore);
1. 如果没有 Trigger 待触发,等候一小段时间后再次检查
2. 假如有一个可用的 Trigger,等待触发它的确切时间的到来
D. 时间到了,为 Trigger 获取到 triggerFiredBundle.
E. 使用 Scheduler和triggerFiredBundle为Job创建一个JobRunShell实例
F. 告诉 ThreadPool 可能时运行 JobRunShell.
这个逻辑存在于 QuartzSchedulerThread 的 run() 方法中。
2.QuartzSchedulerResources
当工厂创建Scheduler实例,它还会传递给Scheduler一QuartzSchedulerResoures实例。QuartzSchedulerResourecs 除包含以上东西之后,还有一个 ThreadPool 实例,它提供了一个工作者线程池来负责执行 Job.在 Quartz 中,ThreadPool 是由 org.quartz.spi.ThreadPool 接口 (因为 Quartz 是在 JDK 1.5 之前产生的,所以需要自己的 ThreadPool 类确保向后的兼容性,Quartz 仍然用自己的 ThreadPool 替代 Java 的) 表示的,并提供一个名为 org.quartz.simp.SimpleThreadPool 的具体实现类。SimpleThreadPool 有一个固定数目的工作者线程,在加载之后就不再减少或增多。下面是它的一个描述图:
大家可以看出,做为执行多个job的Quartz框架,它非常需要一个线程池来管理各个执行Job的线程;毕竟,系统资源有限;
3.什么是 Quartz 工作者线程?
Quartz 不会在 main 线程中处理你的 Job。如果这么做,会严重降低应用的可扩展性。相应的,Quartz 把线程管理的职责委托给分散的组件。对于一般的 Quartz 设置 (这部分还是很费功夫的),都是用SimpleThreadPool 类处理线程的管理。SimpleThreadPool 创建了一定数量的 WorkerThread 实例来使得 Job 能够在分散的线程中进行处理。WorkerThread 是定义在 SimpleThreadPool 类中的内部类,它实质上就是一个线程。要创建 WorkerThread 的数量以及为他们的优先级是配置在文件quartz.properties 中并传入工厂的。
当 QuartzSchedulerThread 请求 ThreadPool (SimpleThreadPool )去运行 JobRunShell 实例,ThreadPool 就检查看是否有一个可用的工作者线程。假如所以已配置的工作者线程都是忙的,ThreadPool 就等待直到有一个变为可用。当一个工作者线程是可用的,并且有一个 JobRunShell 等待执行,工作者线程就会调用 JobRunShell 类的 run() 方法。
4.配置可选择的 ThreadPool
Quartz 框架允许你改变所用的 ThreadPool 实现。替换类必须实现ThreadPool 接口,但是框架只支持通过在文件中配置的方式改变 ThreadPool 的实现类。例如,你可以使用更为高级的 ThreadPool 实现--随时基于需求改变线程的数量,甚至是从应用服务器中获得工作者线程。对于大多数用户,默认的实现就足够了。
5.JobRunShell 的 run() 方法
WorkerThread 是基于于 Java 线程,JobRunShell 类基于实现了 Runable。那意味着它可以作为一个线程并包含一个 run() 方法。JobRunShell 的目的是调用 Job 的 execute() 方法。不仅如此,它还要负责通知 Job 和 Trigger 监听器,在运行完成后还得更新此次执行的 Trigger 的信息。大家可以看出了吧,JobRunShell =Runnable,WorkerThread =Thread;他们是一个依附关系,即一个任务需要由一个线程来进行驱动;
- 大小: 40.4 KB
分享到:
相关推荐
Spring整合任务调度框架Quartz,本文档详细介绍了Spring整合任务调度框架Quartz,希望可以帮助学习者
任务调度框架Quartz, 任务调度框架Quartz, 任务调度框架Quartz
Java任务调度框架Quartz2.0.2(版本:2.0.2)教程实例源代码
Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度
Java任务调度框架Quartz1.8.6(版本:1.8.6)教程实例源代码
LTS是一个轻量级分布式任务调度框架。有三种角色, JobClient, JobTracker, TaskTracker。 4. uncode-schedule 基于zookeeper+spring task的分布式任务调度组件,非常小巧,无需任何修改就可以使spring task具备...
NULL 博文链接:https://baobeituping.iteye.com/blog/629237
任务调度框架Quartz[收集].pdf
任务调度Quartz框架 任务调度Quartz框架
spring quartz 时间任务调度框架 spring quartz 时间任务调度框架 spring quartz 时间任务调度框架
Quartz任务调度框架教程中文版 chm格式
使用Quartz调度任务,根据需要人为的终止某个任务,适用于很多常见的场景
Quartz-2.2.1 任务调度框架在Java项目中的使用实例 Demo 在这个小Demo 中使用了Java 类的反射机制,通用的项目实例,高度抽象...在业务需求不是很复杂的情况下,完全可以减少因为使用Quartz任务调度框架的代码量!!!
spring任务调度(Quartz )非常基础,
Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz框架包含了调度器监听、作业和触发器监听。你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听...
quartz 定时任务调度
制定Quartz.NET调度计划,以及监控Quartz.NET以及Topshelf运行情况 应用场景:定时Job配置以及定时Job运行情况记录
Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的...