2022年任务调度框架Quartz .pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《2022年任务调度框架Quartz .pdf》由会员分享,可在线阅读,更多相关《2022年任务调度框架Quartz .pdf(20页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、任务调度框架 Quartz文档概述各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说: 每隔半个小时生成精华文章的 RSS 文件,每天凌晨统计论坛用户的积分排名,每隔30 分钟执行锁定用户解锁任务。对于一个典型的 MIS 系统来说,在每月 1 号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务,这样的例子俯拾皆是,不胜枚举。任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。 如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。Java 开源的好处就是:领域问题都能找到现成
2、的解决方案。OpenSymphony所提供的 Quartz自 2001 年发布版本以来已经被众多项目作为任务调度的解决方案, Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。此外, Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、
3、线程池等功能。了解 Quartz体系结构Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这 3 个核心的概念, 并在 org.quartz通过接口和类对重要的这些核心概念进行描述:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 20 页 - - - - - - - - - Job :是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionC
4、ontext类提供了调度上下文的各种信息。Job 运行时的信息保存在JobDataMap实例中; JobDetail :Quartz在每次执行 Job 时,都重新创建一个Job 实例,所以它不直接接受一个 Job 的实例,相反它接收一个Job 实现类,以便运行时通过newInstance()的反射机制实例化Job 。因此需要通过一个类来描述Job 的实现类及其它相关的静态信息, 如 Job 名字、描述、关联监听器等信息, JobDetail承担了这一角色。通过该类的构造函数可以更具体地了解它的功用:JobDetail(java.lang.String name, java.lang.Strin
5、g group, java.lang.Class jobClass),该构造函数要求指定 Job 的实现类,以及任务在Scheduler中的组名和 Job 名称; Trigger:是一个类,描述触发Job 执行的时间触发规则。主要有SimpleTrigger和 CronTrigger这两个子类。 当仅需触发一次或者以固定时间间隔周期执行, SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron 表达式定义出各种复杂时间规则的调度方案:如每早晨 9:00执行,周一、周三、周五下午 5:00执行等; Calendar:org.quartz.Calendar和 java
6、.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合 java.util.Calendar代表一个日历时间点,无特殊说明后面的 Calendar即指 org.quartz.Calendar)。一个 Trigger可以和多个 Calendar关联,以便排除或包含某些时间点。假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在 Trigger触发机制的基础上使用Calendar进行定点排除。针对不同时间段类型,Quartz在 org.quartz
7、.impl.calendar包下提供了若干个 Calendar的实现类,如 AnnualCalendar、MonthlyCalendar、WeeklyCalendar分别针对每年、每月和每周进行定义; Scheduler :代表一个 Quartz的独立运行容器, Trigger和 JobDetail可以注册到 Scheduler中,两者在 Scheduler中拥有各自的组及名称, 组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整
8、理 - - - - - - - 第 2 页,共 20 页 - - - - - - - - - JobDetail的组和名称也必须唯一 (但可以和 Trigger的组和名称相同, 因为它们是不同类型的)。 Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和 JobDetail。Scheduler可以将 Trigger绑定到某一 JobDetail中, 这样当 Trigger触发时,对应的 Job 就被执行。一个Job 可以对应多个 Trigger ,但一个 Trigger只能对应一个 Job 。可以通过 SchedulerFactory创建一个 Sched
9、uler实例。Scheduler拥有一个 SchedulerContext,它类似于 ServletContext,保存着 Scheduler上下文信息,Job 和 Trigger都可以访问 SchedulerContext内的信息。 SchedulerContext内部通过一个 Map ,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put() 和 getXxx()的方法。可以通过 Scheduler# getContext()获取对应的 SchedulerContext实例; ThreadPool :Scheduler使用一个线程池作为任务运行
10、的基础设施,任务通过共享线程池中的线程提高运行效率。Job 有一个 StatefulJob子接口,代表有状态的任务, 该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用不同的执行方案。无状态任务在执行时拥有自己的JobDataMap拷贝,对 JobDataMap的更改不会影响下次的执行。而有状态任务共享共享同一个JobDataMap实例,每次任务执行对 JobDataMap所做的更改会保存下来, 后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。正因为这个原因,无状态的Job 可以并发执行,而有状态的StatefulJob不能并发执行,这意味着
11、如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待, 直到前次任务执行完毕。 有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度, 因此除非必要, 应该尽量使用无状态的Job 。如果 Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在 Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。Trigger自身也可以拥有一个JobDataMap,其关联的 Job 可以通过JobExecutionContext#getTrigger().getJobDataMap()获取 Trigge
12、r中的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 20 页 - - - - - - - - - JobDataMap。不管是有状态还是无状态的任务,在任务执行期间对Trigger的 JobDataMap所做的更改都不会进行持久, 也即不会对下次的执行产生影响。Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。图 1 描述了 Sc
13、heduler的内部组件结构, SchedulerContext提供 Scheduler全局可见的上下文信息,每一个任务都对应一个JobDataMap,虚线表达的JobDataMap表示对应有状态的任务:图 1 Scheduler结构图一个 Scheduler可以拥有多个 Triger组和多个 JobDetail组,注册 Trigger和 JobDetail时,如果不显式指定所属的组,Scheduler将放入到默认组中,默认组的组名为 Scheduler.DEFAULT_GROUP。组名和名称组成了对象的全名,同一类型对象的全名不能相同。Scheduler本身就是一个容器,它维护着Quartz
14、的各种组件并实施调度的规则。Scheduler还拥有一个线程池,线程池为任务提供执行线程这比执行任务时简单地创建一个新线程要拥有更高的效率,同时通过共享节约资源的占用。通过线程池组件的支持,对于繁忙度高、压力大的任务调度,Quartz将可以提供良好的伸缩性。提示:Quartz完整下载包 examples目录下拥有 10 多个实例,它们是快速掌握 Quartz应用很好的实例。使用 SimpleTrigger 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 20 页 - -
15、- - - - - - - SimpleTrigger拥有多个重载的构造函数,用以在不同场合下构造出对应的实例: SimpleTrigger(String name, String group):通过该构造函数指定Trigger所属组和名称; SimpleTrigger(String name, String group, Date startTime):除指定Trigger所属组和名称外,还可以指定触发的开发时间; SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, l
16、ong repeatInterval):除指定以上信息外,还可以指定结束时间、重复执行次数、时间间隔等参数; SimpleTrigger(String name, String group, String jobName, String jobGroup, Date startTime, Date endTime, int repeatCount, long repeatInterval):这是最复杂的一个构造函数,在指定触发参数的同时,还通过 jobGroup和 jobName,让该 Trigger和 Scheduler中的某个任务关联起来。通过实现org.quartz.Job 接口,可以使
17、 Java 类化身为可调度的任务。 代码清单 1 提供了 Quartz 任务的一个示例:代码清单 1 SimpleJob:简单的 Job 实现类package com.baobaotao.basic.quartz; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class SimpleJob implements Job 实例 Job 接口方法public void execu
18、te(JobExecutionContext jobCtx)throws JobExecutionException System.out.println(jobCtx.getTrigger().getName()+ triggered. time is: + (new Date(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 20 页 - - - - - - - - - 这个类用一条非常简单的输出语句实现了Job 接口的execute(JobExecutionCo
19、ntext context) 方法,这个方法可以包含想要执行的任何代码。下面,我们通过SimpleTrigger对 SimpleJob进行调度:代码清单 2 SimpleTriggerRunner:使用 SimpleTrigger进行调度package com.baobaotao.basic.quartz; import java.util.Date; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.SimpleTrig
20、ger; import org.quartz.impl.StdSchedulerFactory; public class SimpleTriggerRunner public static void main(String args) try 创建一个 JobDetail实例,指定SimpleJobJobDetail jobDetail = new JobDetail(job1_1,jGroup1, SimpleJob.class); 通过 SimpleTrigger定义调度规则:马上启动,每2 秒运行一次,共运行100 次SimpleTrigger simpleTrigger = new
21、SimpleTrigger(trigger1_1,tgroup1); simpleTrigger.setStartTime(new Date(); simpleTrigger.setRepeatInterval(2000); simpleTrigger.setRepeatCount(100); 通过 SchedulerFactory获取一个调度器实例SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); schedu
22、ler.scheduleJob(jobDetail, simpleTrigger); 注册并进行调度scheduler.start();调度启动 catch (Exception e) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 20 页 - - - - - - - - - e.printStackTrace(); 首先在处通过 JobDetail封装 SimpleJob ,同时指定 Job 在 Scheduler中所属组及名称,这里,组名为jGroup1 ,而名称为
23、 job1_1 。在处创建一个 SimpleTrigger实例, 指定该 Trigger在 Scheduler中所属组及名称。接着设置调度的时间规则。最后,需要创建 Scheduler实例,并将 JobDetail和 Trigger实例注册到Scheduler中。这里,我们通过StdSchedulerFactory获取一个 Scheduler实例,并通过 scheduleJob(JobDetail jobDetail, Trigger trigger)完成两件事:1) 将 JobDetail和 Trigger注册到 Scheduler中;2) 将 Trigger指派给 JobDetail,将两
24、者关联起来。当 Scheduler启动后, Trigger将定期触发并执行SimpleJob的execute(JobExecutionContext jobCtx)方法,然后每10 秒重复一次,直到任务被执行100 次后停止。还可以通过 SimpleTrigger的 setStartTime(java.util.Date startTime)和setEndTime(java.util.Date endTime)指定运行的时间范围,当运行次数和时间范围冲突时,超过时间范围的任务运行不被执行。如可以通过simpleTrigger.setStartTime(new Date(System.curre
25、ntTimeMillis() + 60000L)指定 60 秒钟以后开始。除了通过 scheduleJob(jobDetail, simpleTrigger)建立 Trigger和JobDetail的关联,还有另外一种关联Trigger和 JobDetail的方式:JobDetail jobDetail = new JobDetail(job1_1,jGroup1, SimpleJob.class); SimpleTrigger simpleTrigger = new SimpleTrigger(trigger1_1,tgroup1); 名师资料总结 - - -精品资料欢迎下载 - - - -
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年任务调度框架Quartz 2022 任务 调度 框架 Quartz
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内