一 简介
在生活中,我们经常会制定一些“计划任务”,即在某个时间点做某件事情。同样地,在企业级应用中,也会经常碰到类似的任务调度的需求,下面来看几个例子。在购物网站,每天凌晨统计商品名、商家排名,每天晚上定点统计当日的销量、销售额、盈利等信息并生成报表,每15分钟查询用户的新订单并推送给对应处理人。在社区网站,每天统计用户的在线时长,并按照某种规则给予一定的称号和奖励等。在后台服务中做系统维护,每个工作日的固定时间将数据进行备份。可见,企业应用中离不开灵活的任务调度。
从以上例子可以看到,调度的核心是以时间为关注点,即在一个特定的时间点,系统执行指定的-个操作。任务调度本身涉及多线程并发、运行时间规则解析、运行现场的保护与恢复及线程池维护等。这项非常复杂的工作,可以通过一个开源任务调度框架来实现,它就是Quartz框架。
Quartz框架是一个开源的企业级任务调度服务,它可以被单独使用,也可以整合进任何Java应用,从小型应用到大型的电子商务系统,Quartz已经被作为任务调度的良好解决方案。Quartz提供了强大的任务调度机制,使用也非常简单。Quartz允许开发人员灵活定义调度时间表,提供和任务进行关联的便捷方法,另外,Quartz提供了调度运行环境的持久化机制,使系统出现故障关闭时,任务调度现场数据可以保存下来不致丢失。
1.1 Quartz框架核心概念
Quartz是一款开源框架,为了在应用中使用它,需要在官方网站(http://quartz-scheduler.org)下载Quartz,并添加到项目的classpath中。本文中,我们选用Quatz的1.8.6版本,此版本在项目中应用较多,也较为稳定。
在Quartz完整的下载包中包括docs文件夹和examples'文件夹。其中从docs文件夹中,可以找到Quarz完整的API文档,为开发提供了帮助;另外,examples文件中的多个示例程序,可以让你快速了解Quartz的核心功能。
下面来看一个具体的问题。
例如在某个OA系统中,允许用户制定工作提醒,包括任务时间和任务内容。通过定时任务,对员工张三的工作任务进行提醒,实现每3秒进行一次任务提醒,定时器在10秒后关闭。效果如图所示。
任务调度的核心是支持“某个时间”执行“一个计划任务”,在以上问题中,时间点为“每隔3秒”,执行的任务是“进行工作提醒”,即根据定制的提醒列表输出提醒信息。因此,需要设置一个调度来决定什么时间调用工作提醒任务。Quartz对任务调度进行了高度抽象,提出了3个核心概念一一任务、触发器和调度器,并在org.quartz中通过类和接口对核心概念进行了描述。
1.任务
顾名思义,任务就是执行的工作内容。Quartz提供Job接口来支持任务定义。Job接口的方法声明如下。
public interface Job {
void execue(JobExceutionContextcontext) throws JobExecutionException;
}
Job接口中只有一个execute()方法,开发者需要在自己的任务类中实现该方法,完成具体任务的执行。通过该方法中传人的JobExecutionContext,可以获取调度上下文的各种信息,如任务名称等。
Quartz每次执行Job时,都会创建一个Job实现类的新的实例,JobDetail类就是Job接口的一个实现类。Quartz允许对Job进行分组。
2.触发器
创建的Job要在什么时间定时执行呢?在Quartz中,触发器Trigger类允许定义触发Job执行的时间触发规则。例如,每隔1小时执行一次,每天15:00执行等。Trigger有两个实现类,分别为SimpleTrigger和CronTrigger,两个不同的触发器为不同的应用场景提供支持。
3.调度器
如何将工作任务和触发器绑定,保证任务可以在正确的时间执行呢?Quartz提供了调度器Scheduler类,它是Quartz独立运行的容器。Trigger和JobDetail可以注册到Scheduler中。Scheduler定义了多个接口方法,允许通过组及名称访问容器中的Trigger和JobDetail。Scheduler可以将Trigger绑定到一个JobDetail上,当Trigger被触发后,一个Job就会被执行。通过任务、触发器和调度器,就可以通过Quartz轻松实现任务调度。除此之外,Quartz还对一些特殊场景提供了支持,如Calendar对象。具体的使用在后面的小节会重点讲解。
1.2 quartz框架的使用流程
1. 建立j