2024年3月24日发(作者:)

Quartz任务调度快速入门1

概述

各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成

精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁

定用户解锁任务。

对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生

成月报表,每半个小时查询用户是否已经有快到期的待处理业务„„,这样的例

子俯拾皆是,不胜枚举。

任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、

线程池维护等诸多方面的工作。如果直接使用自定义线程这种刀耕火种的原始办

法,开发任务调度程序是一项颇具挑战性的工作。Java开源的好处就是:领域

问题都能找到现成的解决方案。

OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任

务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所

提供的强大功能使你可以应付绝大多数的调度需求。

Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵

的是它同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调

度时间表,并可以对触发器和任务进行关联映射。

此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,

即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了

组件式的侦听器、各种插件、线程池等功能。

了解Quartz体系结构

Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发

器这3个核心的概念,并在通过接口和类对重要的这些核心概念进

行描述:

●Job:是一个接口,只有一个方法void execute(JobExecutionContext

context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调

度上下文的各种信息。Job运行时的信息保存在 JobDataMap实例中;

●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不

直接接受一个Job的实例,相反它接收一个Job实现 类,以便运行时通过

newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现

类及其它相关的静态信息,如Job名字、描 述、关联监听器等信息,JobDetail

承担了这一角色。

通过该类的构造函数可以更具体地了解它的功用:JobDetail(

name, group, jobClass),该构造函数要

求指定Job的实现类,以及任务在Scheduler中的组名和Job名称;

●Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger

和CronTrigger这两个子类。当仅需触 发一次或者以固定时间间隔周期执行,

SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义

出各种复杂时间规 则的调度方案:如每早晨9:00执行,周一、周三、周五下午

5:00执行等;

●Calendar:ar和ar不同,它是一些日

历特定时间点的集合(可以简 单地将ar看作

ar的集合——ar代表一个日历时 间点,无

特殊说明后面的Calendar即指ar)。一个Trigger可以和

多个Calendar关联,以便排除或 包含某些时间点。

假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任

务则不执行,这时就需要在Trigger触发机制的基础上使用 Calendar进行定点

排除。针对不同时间段类型,Quartz在ar包下提供了

若干个Calendar 的实现类,如AnnualCalendar、MonthlyCalendar、

WeeklyCalendar分别针对每年、每月和每周进行定义;

●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,它类似于ServletContext,保存着

Scheduler上下文信息,Job和 Trigger都可以访问SchedulerContext内的信

息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下 文数

据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。

可以通过Scheduler# getContext()获取对应的SchedulerContext实例;

Quartz任务调度快速入门2

●ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过

共享线程池中的线程提高运行效率。

Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的

标签接口,其目的是让Quartz知道任务的类型,以便采用 不同的执行方案。无