1.Quartz 是用来完成任务调度的。

2.Quartz 的三个核心概念:调度器、任务、触发器。

(1)Job:通过实现该接口来定义需要执行的任务。

public interface Job {

    /**
* Called by the <code>{@link Scheduler}</code> when a <code>{@link Trigger}</code> fires that is associated with the <code>Job</code>.
*/
void execute(JobExecutionContext context) throws JobExecutionException;
}

(2)JobDetail:Quartz 在每次执行 Job 时,都重新创建一个 Job 实例,所以它不是直接接受一个 Job 的实例,而是接受 Job 的一个实现类,以便运行时通过反射区实例化 Job。

JobDtail 就是用来描述 Job 的实现类以及其他相关的静态信息。

package org.quartz;

import java.io.Serializable;

/**
* Conveys the detail properties of a given <code>Job</code> instance. JobDetails are
* to be created/defined with {@link JobBuilder}.
*
* <p>
* Quartz does not store an actual instance of a <code>Job</code> class, but
* instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
* </p>
*
* <p>
* <code>Job</code>s have a name and group associated with them, which
* should uniquely identify them within a single <code>{@link Scheduler}</code>.
* </p>
*
* <p>
* <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
* are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
* but a single <code>Trigger</code> can only point to one <code>Job</code>.
* </p>*/
public interface JobDetail extends Serializable, Cloneable { public JobKey getKey(); public String getDescription(); public Class<? extends Job> getJobClass(); public JobDataMap getJobDataMap(); public boolean isDurable(); public boolean isPersistJobDataAfterExecution(); public boolean isConcurrentExectionDisallowed(); public boolean requestsRecovery(); public Object clone(); public JobBuilder getJobBuilder(); }

(3)Trigger(中文"触发"的意思):描述出发 Job 执行的时间触发规则。

package org.quartz;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.ScheduleBuilder;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey; /**
* The base interface with properties common to all <code>Trigger</code>s -
* use {@link TriggerBuilder} to instantiate an actual Trigger.
*
* <p>
* <code>Triggers</code>s have a {@link TriggerKey} associated with them, which
* should uniquely identify them within a single <code>{@link Scheduler}</code>.
* </p>
*
* <p>
* <code>Trigger</code>s are the 'mechanism' by which <code>Job</code>s
* are scheduled. Many <code>Trigger</code>s can point to the same <code>Job</code>,
* but a single <code>Trigger</code> can only point to one <code>Job</code>.
* </p>
*
* <p>
* Triggers can 'send' parameters/data to <code>Job</code>s by placing contents
* into the <code>JobDataMap</code> on the <code>Trigger</code>.
* </p>
*
* @see TriggerBuilder
* @see JobDataMap
* @see JobExecutionContext
* @see TriggerUtils
* @see SimpleTrigger
* @see CronTrigger
* @see CalendarIntervalTrigger
*
* @author James House
*/
public interface Trigger extends Serializable, Cloneable, Comparable<Trigger> {
long serialVersionUID = -3904243490805975570L;
int MISFIRE_INSTRUCTION_SMART_POLICY = 0;
int MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1;
int DEFAULT_PRIORITY = 5; TriggerKey getKey(); JobKey getJobKey(); String getDescription(); String getCalendarName(); JobDataMap getJobDataMap(); int getPriority(); boolean mayFireAgain(); Date getStartTime(); Date getEndTime(); Date getNextFireTime(); Date getPreviousFireTime(); Date getFireTimeAfter(Date var1); Date getFinalFireTime(); int getMisfireInstruction(); TriggerBuilder<? extends Trigger> getTriggerBuilder(); ScheduleBuilder<? extends Trigger> getScheduleBuilder(); boolean equals(Object var1); int compareTo(Trigger var1); public static class TriggerTimeComparator implements Comparator<Trigger>, Serializable {
private static final long serialVersionUID = -3904243490805975570L; public TriggerTimeComparator() {
} public static int compare(Date nextFireTime1, int priority1, TriggerKey key1, Date nextFireTime2, int priority2, TriggerKey key2) {
if(nextFireTime1 != null || nextFireTime2 != null) {
if(nextFireTime1 == null) {
return 1;
} if(nextFireTime2 == null) {
return -1;
} if(nextFireTime1.before(nextFireTime2)) {
return -1;
} if(nextFireTime1.after(nextFireTime2)) {
return 1;
}
} int comp = priority2 - priority1;
return comp != 0?comp:key1.compareTo(key2);
} public int compare(Trigger t1, Trigger t2) {
return compare(t1.getNextFireTime(), t1.getPriority(), t1.getKey(), t2.getNextFireTime(), t2.getPriority(), t2.getKey());
}
} public static enum CompletedExecutionInstruction {
NOOP,
RE_EXECUTE_JOB,
SET_TRIGGER_COMPLETE,
DELETE_TRIGGER,
SET_ALL_JOB_TRIGGERS_COMPLETE,
SET_TRIGGER_ERROR,
SET_ALL_JOB_TRIGGERS_ERROR; private CompletedExecutionInstruction() {
}
} public static enum TriggerState {
NONE,
NORMAL,
PAUSED,
COMPLETE,
ERROR,
BLOCKED; private TriggerState() {
}
}
}

主要有两个实现类:

  • SimpleTrigger:当仅需要触发一次或者以固定间隔周期执行。
  • CronTrigger:可以通过 Cron 表达式定义出各种复杂的调度方案。

(4)Calendar:一些日历特定时间点的集合。一个 Trigger 可以和多个 Calendar 关联,以便包含或排除某些时间点。

(5)Scheduler:一个 Quartz 的独立运行容器,Trigger 和 JobDtail 可以注册到 Scheduler 中。

Scheduler 可以将 Trigger 绑定到某一个 JobDetail 中,这样当 Trigger 被触发时,对应的 Job 就被执行。

一个 Job 可以有多个对应的 Trigger ,但是一个 Trigger 只能对应一个 Job。

3. HelloWorld

(1)步骤:

  • 实现 Job 接口,可使 Java 类变为可调度的任务
  • 创建描述 Job 的 JobDetail 对象
  • 创建 Trigger 对象
  • 设置触发 Job 执行的时间规则
  • 通过 SchedulerFactory 获取 Scheduler 对象
  • 向 SchedulerFactory 中注册 JobDetail 和 Trigger
  • 启动调度任务

(2)SimpleTrigger

/**
* @author solverpeng
* @create 2016-09-25-14:56
*/
public class HelloWorld { public static void main(String[] args) throws SchedulerException, ParseException { JobDetailImpl jobDetail = new JobDetailImpl(); jobDetail.setGroup("test-group"); jobDetail.setName("test-name");
jobDetail.setJobClass(MyJob.class); SimpleTriggerImpl trigger = new SimpleTriggerImpl();
trigger.setName("test-trigger-name");
trigger.setGroup("test-trigger-group");
trigger.setStartTime(new Date());
trigger.setRepeatCount(5);
trigger.setRepeatInterval(1000*5); SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } }

(3)CronTrigger

Cron 表达式1:

  • 由6或7个空格分割的时间字段组成
  • 对特殊字符的大小写不敏感
  • 从左到右时间范围越来越大:秒 分 时 日 月 星期 年(可选)
  • 秒:范围:0-59,允许特殊字符 ", - * /"
  • 分:范围:0-59,允许特殊字符 ", - * /"
  • 小时:范围:0-23
  • 日期:范围:1-31
  • 星期:范围:1-7(需要用英文简写表示)
  • 年:范围:控制或 1970-2099

Cron 表达式2:

  • * :可用于所有字段,表示每一个时刻。e: * 分钟时段表示每分钟
  • ? :只能使用在日期和星期字段,表示一个毫无意义的值。相当于占位符。(日期和星期字段必须有一个 ? ,不能使用 * 替代)
  • - :表示一个范围。e: 10-12 使用在小时字段,表示10点、11点、12点
  • , :表示一个列表值。e:在星期字段中使用 MON,WED,FRI,表示星期一,星期三,星期五
  • / :x/y 表示一个等步长序列,x 为起始值,y 为增量步长。
    • e1:在分钟字段使用 0/15 ,则表示 0,15,30 和 45 秒;
    • e2:5/15,表示5,20,35,50。
    • */y 等同于 0/y。
  • L :只在日期和星期字段中使用,代表 Last。
    • 使用在日期字段,表示这个月的最后一天;
    • 使用在星期字段,表示星期六。
    • 若 L 出现在星期字段里,且前面有一个数值X,则表示这个月的最后星期X,例如 6L 表示该月的最后一个星期五。
  • W :只能出现在日期字段中,是对前导日期的修饰,表示离该日期最近的工作日。
    • e1:15W 表示离该月15号最近的工作日,若15号是星期六,则匹配14号,若15号是星期日,则匹配16号,若15号是星期二,则匹配15号。
    • 关联的匹配日期不能跨月。如用户指定1W,若1号是星期六,则匹配3号
    • W 只能指定单一日期,而不能指定日期范围
  • LW :在日期字段可以组合使用LW,值 当月的最后一个工作日
  • # :只能在星期字段中使用,表示当月某个工作日,如:6#3 表示当月的第三个星期5,4#5 表示当月第5个星期三。
  • C :该字段只在日期和星期字段中使用,代表 Canlendar。指计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。
    • 5C在日期字段中相当于 5 日以后的第一天  
    • 1C在星期字段中相当于星期日后的第一天

Cron表达式示例

  • 0 0 12 * * ?:每天中午12点触发
  • 0 15 10 ? * *:每天上午10:15触发
  • 0 15 10 * ? *: 每天上午10:15触发
  • 0 15 10 * * ?: 每天上午10:15触发
  • 0 15 10 * * ? 2005: 2005年的每天上午10:15触发
  • 0 * 14 * * ?:在每天下午2点到下午2:59期间的每1分钟触发
  • 0 0/5 14 * * ?:在每天下午2点到下午2:55期间的每5分钟触发
  • 0 0/5 14, 18 * * ?:在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟,触发
  • 0 0-5 14 * * ?:在每天下午2点到下午2:05期间的每1分钟触发
  • 0 10,44 14 ? 3 WED:每年三月的星期三的下午2:10和2:44触发
  • 0 15 10 ? * MON-FRI:周一至周五的上午10:15 触发
  • 0 15 10 15 * ?:每月15日上午10:15 触发
  • 0 15 10 L * ?:每月最后一日的上午10:15 触发
  • 0 15 10 ? * 6L:每月的最后一个星期五上午10:15 触发
  • 0 15 10 ? * 6L 2002-2005:2002年至2005年的每月的最后一个星期五上午10:15触发
  • 0 15 10 ? * 6#3:每月的第三个星期五上午10:15触发

例子:

/**
* @author solverpeng
* @create 2016-09-25-14:56
*/
public class HelloWorld {
public static void main(String[] args) throws SchedulerException, ParseException { JobDetailImpl jobDetail = new JobDetailImpl(); jobDetail.setGroup("test-group"); jobDetail.setName("test-name");
jobDetail.setJobClass(MyJob.class); CronTriggerImpl trigger = new CronTriggerImpl(); trigger.setCronExpression("0/5 56 15 ? 9 SUN"); trigger.setStartTime(new Date());
trigger.setName("test-trigger-name"); trigger.setGroup("test-trigger-group"); SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start(); } }

官方 Demo:

package com.nucsoft.quartz;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory; import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger; /**
* @author solverpeng
* @create 2016-09-25-16:49
*/
public class HelloWorld { public static void main(String[] args) throws SchedulerException {
// define the job and tie it to our MyJob class
JobDetail job = newJob(MyJob.class).withIdentity("job1", "group1").build(); // Trigger the job to run now, and then repeat every 40 seconds
Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(
simpleSchedule().withIntervalInSeconds(40).repeatForever()).build();
// Grab the Scheduler instance from the Factory
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger); // and start it off
scheduler.start();
} }

4.总结

介绍了Quartz的几个核心概念,Cron 表达式,以及 Quartz 的 HelloWorld。Job 是用来定义要完成的任务,JobDetail用来描述它,Trigger 是一个触发器,用于触发任务,它们统一由 Scheduler

来管理。其中需要注意一点的是,国外每个星期的开始是从 星期日开始的,所以 6 表示星期五。

Quartz —— 从 HelloWorld 开始的更多相关文章

  1. quartz(1)

    关于定时任务的操作方法,java语言本身具有 Timer 来解决,但Timer 作用起来不是特别的舒服,由于项目的需要,使用了Quartz 这个调度框架,现把学习过程记录下来,方便以后查阅. 本教程是 ...

  2. Quartz.net2.2初体验

    简介:Quartz.net是一个开源的作用调度框架,非常强大,能够通过简单的配置帮助我们定时具体的操作.相对于我们用的线程里面while(true)然后sleep来执行某个操作,应该算的上是高端,大气 ...

  3. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  4. 定时组件quartz系列<三>quartz调度机制调研及源码分析

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  5. Spring中Quartz的配置

    Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在Spring中怎样配置Quartz: 首先,来写一个测试被调度的类:(QuartzHelloWorldJ ...

  6. (1)quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析 原文地址:http://demo.netfoucs.com/gklifg/article/details/27090179 引言quartz集群架构调 ...

  7. quartz群调查调度机制和源代码分析

    pageId=85056282#quartz集群调度机制调研及源代码分析-quartz2.2.1集群调度机制调研及源代码分析" style="color:rgb(59,115,17 ...

  8. quartz笔记

    首先网络上的很多教程经常有错(信息过载了),其主要原因是版本发生了变化,例如quartz1和2之间还是有不少差别的,导致查找资料的人浪费了不少时间.所以无论教程如何写,都建议读者首先学习官网的教程,如 ...

  9. 【Quartz】1、Quartz使用说明

    简介 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多对多关系,还 ...

随机推荐

  1. UVA-146 ID Codes

    It is 2084 and the year of Big Brother has finally arrived, albeit a century late. In order to exerc ...

  2. GOF23设计模式归类

    创建型模式:-单例模式.工厂模式.抽象工厂模式.建造者模式.原型模式结构型模式:-适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式行为型模式:-模板方法模式.命令模式.迭代器模式 ...

  3. 太多选择——企业如何选择合适的BI工具?

    在没认清现状前,企业当然不能一言不合就上BI. BI不同于一般的企业管理软件,不能简单归类为类似用于提高管理的ERP和WMS,或用于提高企业效率的OA.BPM.BI的本质应该是通过展现数据,用于加强企 ...

  4. XAMARIN.ANDROID SIGNALR 实时消息接收发送示例

    SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...

  5. WebAPI

    WebAPI的Host OWIN IIS WebAPI 的handler和Filter有啥区别? WebAPI  常用 Filters Exception Filter Timer Filter Lo ...

  6. 初尝Brnshop移植到Linux Mono Jexus环境运行

    brnshop是最近社区上比较火的开源商城. Jexus是Linux上的web服务器,简单说就是Linux的iis吧.特别感谢作者宇内流云的指点 一.根据http://www.cnblogs.com/ ...

  7. .NET面试题系列[2] - .NET框架基础知识(2)

    3 程序集 面试出现频率:虽然很重要但不怎么出现,可能会考你定义,以及程序集包括什么,然后自然的话题就跑到反射上去了. 重要程度:8/10,很重要 需要理解的程度:知道程序集包括IL和元数据.知道元数 ...

  8. 【腾讯Bugly干货分享】Android Patch 方案与持续交付

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a31921ac3a1fb613dd40f3 Android 不仅系统版本众多 ...

  9. CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率

    CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率 当场景中有比较复杂的模型时,条件渲染能够加速对复杂模型的渲染. 条件渲染(Conditio ...

  10. Gulp探究折腾之路(I)

    前言: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器:她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成:使用她,我们不仅可以很愉快的编写代码 ...