前序:
     做为企业里的任务调度框架,出现同一时间点同时运行两个任务,或者两个任务因为开始的执行时间和执行时间的长短,很有可能出现任务并发执行的情况;因为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;他们是一个依附关系,即一个任务需要由一个线程来进行驱动;

企业级任务调度框架Quartz(8) 线程在Quartz里的意义(2)的更多相关文章

  1. Quartz:不要重复造轮子,一款企业级任务调度框架。

    背景 第一次遇到定时执行某些任务的需求时,很多朋友可能设计了一个小类库,这个类图提高了一个接口,然后由调度器调度所有注册的接口类型,我就是其中之一,随着接触的开源项目越来越多,我的某些开发习惯受到了影 ...

  2. 企业级任务调度框架Quartz(6) 任务调度器(Scheduler)

    前序:      我们已经在前面的内容能里看到了,我们用 Scheduler 来管理我们的 Job:创建并关联触发器以使 Job 能被触发执行:以及如可选择 calendar 为给定的时程安排提供更多 ...

  3. 企业级任务调度框架Quartz(5) Quartz的声明式配置

    前序:     前面我们已经通过编程的方式实现了多个作业任务执行具体操作的演示:但具体到实际的时候,如果我们要在 Job 启动之后改变它的执行时间和频度,则必须去修改源代码重新编译,我们很难去以编程的 ...

  4. 企业级任务调度框架Quartz(1) --企业应用中的任务调度介绍

    由于目前的工作内容为建行CLPM批处理业务的设计工作,所以很好的理解批处理所用的任务调度框架Quartz势在必行:为了能够更好的去服务于工作,也 为了提升自己,所以我学习了Quartz Job Sch ...

  5. 企业级任务调度框架Quartz(3) 一个简单的Quartz 例子

    1. 一个简单的Quartz 工程     本示例应用比起众所周知的 System.out.println("Hello world from Quartz") 来还是要有趣些.当 ...

  6. 企业级任务调度框架Quartz(4) 多个job实例注册到任务调度器上

    前序:     在第一个例子我看到了自定义的作业类在任务调度器上注册后,则通过任务调度器来实现启动:下面,我们将同一个作业类执行两个任务,并都将他们注册到任务调度器上!     首先一个job类指向两 ...

  7. 企业级任务调度框架Quartz(2)-下载和安装Quartz

    1.下载和安装 Quartz 根据资料上提供的网址http://www.opensymphony.com/quartz 我们可以下载到Quartz的最新版本1.6.4: 2.下载后包的说明       ...

  8. 企业级任务调度框架Quartz(7) 线程在Quartz里的意义(1)

    1.Java 中的线程     线程允许程序同一时间做很多任务,至少,看起来那些任务是并发执行的.在我的并发编程的帖子里有介绍线程的基本概念:我们知道在任一特定时刻仅有一个线程 在执行,但是 CPU ...

  9. 企业级任务调度框架Quartz(9) Quartz之作业触发器Trigger

    前序:      我们已经大概对Quartz的基本有了一个大概的认识:现在我们将要逐渐对Quartz的各个重要组件进行学习:前面已经对job进行了详细讲解,现在我们来认识下它的一个重要兄弟,没有它,作 ...

随机推荐

  1. 解决@vue/cli 创建项目是安装chromedriver时失败的问题

    最近在使用新版vue的命令行工具创建项目时,安装chromedriver老是失败,导致后面的步骤也没有进行.网上搜索了一下,全是使用 工作中常见问题汇总及解决方案 npm install chrome ...

  2. Vue packages version mismatch

    开发过程中,之前做的vue项目,一段时间后拿出来重新运行,报错: 打开vue-template-compiler/index.js查看错误提示,如下: 当安装的vue版本和package.json中的 ...

  3. SBC37x交叉编译平台QT+OPENCV

    一.构建交叉编译器 [随机手册]Angstrom是一个界面友好的嵌入式发行版本,用亍手持设备,机顶盒和网络存储设备等嵌入式设备. 光盘的文件系统是定制的The Angstrom Distributio ...

  4. VC2010常见问题的解决方案

    vc++里面的obj文件是什么文件Project(项目)中每个cpp经编译成为obj(object)目标文件,所有obj文件和资源文件经链接(link)成为可执行文件,obj文件可称为目标文件或中间文 ...

  5. 使用idea搭建maven项目时 java目录下的xml文件没有加载的解决方法

    今天在idea集成开发环境下 使用maven搭建了ssm项目,遇到了3个问题 首先我们先复习一下知识点: 第一步:在web.xml中配置spring监听器 <!-- spring监听器 加载sp ...

  6. 洛谷 P2046 BZOJ 2007 海拔(NOI2010)

    题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...

  7. 【ACM】hdu_1093_A+BV_201307261715

    A+B for Input-Output Practice (V)Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  8. Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全)

    快过节了.谢谢了屈原,我们爱你. 应该多几个向屈大人一样跳江的,这样我们就能够放假纪念啦. ---------------------------------快过节了.弄个案例,大家最好还是假期做做, ...

  9. java,wavToMP3格式转换

    这里须要用到一个jar包:jave-1.0.1.jar,下载地址的话自己百度吧. 废话不多说直接贴代码: import it.sauronsoftware.jave.AudioAttributes; ...

  10. VC++玩转Native Wifi API 2---Wifi on与wifi off

     有心栽花花不开,无心插柳柳成排. 今天要说的这个wifi on\off是在软件层面控制无线网卡的开和关. 问题听起来简单,调查起来复杂.但解决起来却也简单.关键函数便是Native wifi a ...