Quartz是开源任务调度框架中的翘楚,它提供了强大的 任务调度机制。Quartz允许开发人员灵活的定义触发器的调度时间表,并可对触发器和任务进行关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。

一、Quartz基础结构

        Quartz对任务调度的领域问题进行了高度抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类的核心概念进行描述。
         1)Job:是一个接口,只有一个方法void execute(JobExecutionContext   context) ,开发者实现该接口定义需要执行的任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中。
         2)JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不是直接接受一个Job的实例,而是接收一个Job实现类,以便运行时通过newInstance()的反射调用的机制实例化Job。因此需要通过一个类来描述Job的实现类及其他相关的静态信息,如Job名称、描述、关联监听器等信息,JobDetail承担了这一角色。通过该类的构造函数可以更具体地了解它的功用:JobDetail(java.lang.String
name,java.lang.String group,java.lang.Class   jobClass),该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称。 
        3)Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需要触发一次或者以固定间隔周期性执行,SimplegTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂的调度方案:如每天早晨9:00执行,每周一、周三、周五下午5:00执行等。
        4)Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合------java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar).一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。针对不同的时间段类型,Quartz在org.quartz.impl.calendar包下提供了若干个Calendar的实现类,如AnnualCalendar、MonthlyCalendar、WeekleyCalendar分别针对每年、每月和每周进行定义。
        5)Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称。组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称的组合必须唯一,JobDetail的组和名称的组合也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的,处在不同的集合中)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中的Trigger和JobDetail。Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger被触发时,对应的Job就被执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job.
可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,保存着Scheduler上下文信息,可以对照你熟悉的ServletContext来理解SchedulerContext。Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx方法。可以通过Scheduler#getContext()获取对应的SchedulerContext实例。
       6)ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

二、有状态的任务和无状态的任务

        Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的就是让Quartz知道任务的类型,以便采取不同的执行方案。无状态任务在执行时拥有自己的JobDataMap复制,对JobDataMap的更改不会影响下次的执行。而有状态的任务共享一个JobDataMap实例,每次任务执行时对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,即每次执行任务后都会对后面的执行发生影响。
        正因为这个原因,无状态的Job可以并发执行,而有状态的StatefulJob不能并发执行,这意味着如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。有状态任务比无状态任务需要考虑更多的因素,程序往往更复杂,因此除非必要,应尽量避免使用有状态的Job.
        如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保存一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。
        Trigger自身也可以拥有一个JobDataMap,期关联的JobDataMap可以通过JobExecutionContext#getTrigger().getJobDataMap获取。不管有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMao所做的更改都不会进行持久化,即不会对下次任务的执行产生影响。

        Quartz拥有完善的事件和监听体系,大部分组件都拥有事件、如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等,可以注册相应的监听器处理感兴趣的事件。
       下图描述了Scheduler的内部组件结构,SchedulerContext提供Scheduler全局可见的上下文信息,每一个任务都对应一个JobDataMap,虚线表达的JobDataMap表示对应有状态的任务:
                                                           
一个Scheduler可以拥有多个Trigger和多个JobDetail,它们可以分到不同的组中。注册Trigger和JobDetail时,如果不显示指定所属的组,Scheduler将放入到默认组中,默认组的组名为Scheduler.DEFAULT_GROUP。组名和名称组成了对象的全名。同一类型对象(即Job或Trigger)的全名不能相同。
Scheduler本身就是一个容器,它维护者Quartz的各种组件并实施调度的规则。Scheduler还拥有一个线程池,线程池为任务提供执行线程-----这比执行任务时简单的创建一个新线程要拥有更高的效率,同时通过共享机制减少资源的占用。通过线程池组件的支持,对于繁忙度高、压力大的任务调度,Quartz可以提供良好的伸缩性。


注:Quartz完整下载包examples目录下拥有10多个实例,它们是快速掌握Quartz应用很好的实例.




Quartz学习笔记1:Quartz概述的更多相关文章

  1. Quartz学习笔记:集群部署&高可用

    Quartz学习笔记:集群部署&高可用 集群部署 一个Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点.这就意味着你必须对每个节点分别启动或停止.Quartz集群 ...

  2. Quartz学习笔记:基础知识

    Quartz学习笔记:基础知识 引入Quartz 关于任务调度 关于任务调度,Java.util.Timer是最简单的一种实现任务调度的方法,简单的使用如下: import java.util.Tim ...

  3. OGG学习笔记01-基础概述

    OGG学习笔记01-基础概述 OGG(Oracle Golden Gate),最近几年在数据同步.容灾领域特别火,甚至比Oracle自己的原生产品DataGuard还要风光,主要是因为其跨平台.跨数据 ...

  4. Quartz学习--二 Hello Quartz! 和源码分析

    Quartz学习--二  Hello Quartz! 和源码分析 三.  Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...

  5. 作业调度框架 Quartz 学习笔记(三) -- Cron表达式 (转载)

    前面两篇说的是简单的触发器(SimpleTrigger) , SimpleTrigger 只能处理简单的事件出发,如果想灵活的进行任务的触发,就要请出 CronTrigger 这个重要人物了. Cro ...

  6. quartz学习笔记(一)简单入门

    前言 quartz是Java编写的一款开源的任务调度开发框架,在项目开发中很多场景都可以用到,比如订单超期自动收货. 所谓程序源于生活,生活中也有很多场景可以用quartz来模拟,比如工作日早上七点起 ...

  7. Quartz学习笔记

    :30发送email通知客户最新的业务情况. java.util.Timer和java.util.TimerTask    Timer和TimerTask是能够完毕job schedule的两个jdk ...

  8. Quartz学习——Spring和Quartz集成详解(三)

    Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度.下面就对Spring集成Quartz进行简单的介绍和示例讲解!和上一节 Quar ...

  9. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  10. Flink学习笔记:Connectors概述

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

随机推荐

  1. hadoop in hue的搭建(基于cdh版本)

    首先官网下载tar包 http://archive.cloudera.com/cdh5/cdh/5/hue-3.9.0-cdh5.5.4.tar.gz 在安装hue之前,还需要安装各种依赖包,首先要检 ...

  2. [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  3. hibernate--HelloWorld

    本次学习版本:hibernate-release-5.2.6.Final,要求java 1.8 和JDBC 4.2. hibernate是一个开放源代码的对象关系映射框架.对JDBC进行了非常轻量的封 ...

  4. 重载运算符“ <<” 和“>>” 运算符

    :" <<  "   "  >>  " 的重载作为友元函数重载,有两种方法:1,把变量作为public,就可以不用友元声明:2,先友元声 ...

  5. Linear Regression with Scikit Learn

    Before you read  This is a demo or practice about how to use Simple-Linear-Regression in scikit-lear ...

  6. [JSOI2008]球形空间产生器

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...

  7. [FJOI2007]轮状病毒

    题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律 ...

  8. [HNOI2008]玩具装箱TOY

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  9. ●洛谷P3688 [ZJOI2017]树状数组

    题链: https://www.luogu.org/problemnew/show/P3688题解: 二维线段树. 先不看询问时l=1的特殊情况. 对于一个询问(l,r),如果要让错误的程序得到正确答 ...

  10. ●BZOJ 2743 [HEOI2012]采花

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2743 题解: 树状数组,离线 求区间里面有多少种出现次数大于等于 2 的颜色. 类似某一个题 ...