一、Quartz简介
Java中的定时器通常分为三种,分别为Java.util.Timer、OpenSymphony社区提供的Quartz插件、Spring自带的定时器task。
1、三者的简单比较
- Java自带的java.util.Timer类:允许你调用一个java.util.TimerTask任务,可以让我们的程序按照某一频度执行,但不能在指定的时间运行,一般在项目中用的比较少。
- Quartz:是一个功能比较强大的调度器,可以让我们的程序在指定的时间内执行,也可以按照某个频度执行,在项目中比较用的多。
Spring自带的task:Spring 3.0以后才出现自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
2、quartz介绍
在官网(quartz官网)上是这样介绍它的:
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
用我的英语翻译水平简单粗暴的翻译过来就是:
Quartz 是一种功能丰富的开源作业框架,它可以几乎集成了从最小的独立的应用程序到最大复杂的电子商务系统。Quartz可以被用于创建简单的或者复杂的任务去执行数十,数百甚至数万的作业。任务是被定义为标准的Java组件,可以执行几乎任何可以对其编程的任务,Quartz Scheduler包含许多企业级的功能,比如像JTA事务与集群的功能。
二、Quartz简单实现
1、环境准备
我是用的Eclipse+Maven
创建好java web的Maven项目之后在pom.xml中加入->右键项目->Maven->Update Project:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
或者右键项目->Maven->Add Dependency->搜索本地reposity仓储中的quartz-scheduler.jar与quartz-jobs.jar
2、代码实现
(1)创建job作业类MyJob.java,实现Job接口,override Job中的execute方法。
package com.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class Myjob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("=======execute正在运行=======");
}
}
(2)创建main主线程调用job任务的测试类QuartzTest.java
package com.quartz;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
/**
* job任务调度
* @author Jian
*
*/
public class QuartzTest
{
public static void main( String[] args ){
QuartzTest.quartz();
}
public static void quartz() {
Scheduler scheduler = null;
JobDetail jobDetail = null;
Trigger trigger = null;
try {
// 1、在StdSchedulerFactory工厂中获取一个scheduler实例
scheduler = StdSchedulerFactory.getDefaultScheduler();
// 2、设置job信息
jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("Job001", "MyJobgroup001").build();
// 3、设置触发器信息
trigger = newTrigger().withIdentity("trigger001", "MyTrigroup001").startNow()// 一旦加入scheduler,立即生效
.withSchedule(simpleSchedule() // 使用静态SimpleTrigger
.withIntervalInSeconds(5) // 每隔5秒执行一次
.repeatForever()) // 一直执行
.build();
// 4、 将jobDetail与trigger注册绑定到调度器
scheduler.scheduleJob(jobDetail, trigger);
// 5、任务调度
scheduler.start();
// 6、运行一段时间后关闭,15m以后停止->则job执行4次
Thread.sleep(15000);
scheduler.shutdown(true);
} catch (Exception e) {
System.out.println("任务调度失败!");
e.printStackTrace();
}
}
}
(3)结果输出:每隔5m执行一次Myjob,一共执行了4次。
三、Quartz体系结构
1、Job:是一个接口,里面只有一个方法execute,在实现接口的时候,要在execute方法中编写我们需要定时执行的任务。
其中JobExecutionContext类是提供了调度应用的一些信息,Job运行时的信息将会保留在JobDataMap中。
2、JobDetail:
quartz每次调读job时候,不会去直接一次性接受Job的实例,而是每调度一次就会创建一个Job实例,这样就可以规避并发访问的问题
JobDetail是用来描述Job实现类相关的信息,比如Job名字,描述,关联监听器等信息
3、Trigger:
- 用来描述Job执行的时间触发规则
- 主要分为SimpleTrigger和CronTrigger这两个子类,当以固定的时间来执行调度或者只需要调度一次的情况,则SimpleTrigger是最合适的选择;如果是较为复杂的调度方式(如具体到每天的哪个时间段等),则CronTrigger通过Cron表达式定义复杂的调度方式
4、Scheduler:
- 首先,Scheduler是整个Quartz的核心部分,所有的Job都是由它来实施的,它表示是一个Quart独立运行的容器,Trigger和JobDetail可以注册到Scheduler中,它们都有各自的name与group,name与group两者结合可以唯一确定Trigger与JobDetail在Scheduler中某一对象。
- Scheduler将Tirgger绑定在JobDetail上,一个JobDetail可以绑定多个Trigger,而一个Trigger只能绑定一个JobDetail。
- 通过SchedulerFactory创建一个Scheduler实例,Scheduler也有Scheduler一个SchedulerContext上下文信息。
下图是Scheduler内部组件结构:
5、 Calendar:不同于java.util.Calendar, 它是一些日历特定时间点的集合, 一个Trigger可以和多个Calendar关联, 以便排除或包含某些时间点。比如我们每个星期要排除掉周末两天,让Job任务不执行,这时就用org.quartz.impl.Calendar排除,它有实现类:AnnualCalendar(每年)、MonthlyCalendar(每月)、WeeklyCalendar(每周)
6、ThreadPool: Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。