定时任务调度工具之Quartz(一)

定时任务调度工具之Quartz(一)

一、Quartz介绍

1.特点

(1)强大的调度功能:作为spring默认的调度框架,很容易与spring集成,实现灵活可配置的调度功能;
还提供了调度运行环境的持久化机制,可以保存并恢复调度现场,
即使系统因故障关闭,任务调度现场数据并不会丢失。

(2)灵活的应用方式:允许开发者灵活的定义触发器的调度时间表并可以为触发器和任务进行关联映射。

(3)分布式和集群能力。

2.主要用到的设计模式

Builder模式
Factory模式
组件模式
链式写法

3.三个核心概念

调度器:负责定期定时定频率的去执行任务
任务:包括了业务逻辑
触发器:让东西生效的时间

4.Quartz的体系结构

1.jpg

5.重要组成

(1)Job:

区别与JobDetail,是一个接口,只有一个方法void execute(JobExecutionContext context),
开发者可以实现该接口定义运行任务,相当于TimerTask下面的run()方法,区别在于,
Job有一个参数JobExecutionContext,JobExecutionContext这
个类提供了调度上下文的各种信息,Job运行时的信息就保存在
JobExecutionContext里的JobDataMap实例中。

(2)JobDetail:

Quartz在每次执行实例的时候都重新创建一个job实例,所以它不直接接受一个job实例,
而是通过接受一个job实现类,以便运行时通过new Instance()的反射机制实例化job,
因此需要通过一个类来描述job的实现类及其他相关静态信息,如job的名字,描述,关联监听器等信息。
(即用来绑定job,并且在job执行的时候携带一些执行的信息)
通过该类的构造函数可以更具体地了解它的功用:
JobDetail(java.lang.String name, java.lang.String group, java.lang.Class jobClass),
该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称;

(3)JobBuilder:

用来定义或者创建JobDetail的实例,JobDetail限定了只能是job的实例。

(4)JobStore:

接口,用来保存job数据,实现类主要有RAMJobStore,JobStoreTX,JobStoreCMT;
JobStoreTX和JobStoreCMT均将数据保存在数据库中,
RAMJobStore将数据保存在内存中,保存一些执行的信息。

(5)Trigger:

一个类,描述触发的job执行时的时间触发规则;主要有SimpleTrigger和CronTrigger两个子类。
当仅触发一次或者以固定时间间隔周期执行时,使用SimpleTrigger;
CronTrigger通过cron表达式,定义出各种复杂时间规则的调度方案,
如每天早晨的固定时间执行,或周二周三的固定时间执行等需求。

(6)TriggerBuilder:

使用builder模式,用来定义或者创建触发器的实例

(7)ThreadPool:

Timer有且只有一个后台线程在执行,Quartz的schedule下有ThreadPool整个线程池来运行,
schedule使用线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行的效率,
从而解决并发问题

(8)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,以键值对的方式维护这些上下文数据,S
chedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。
可以通过Scheduler# getContext()获取对应的SchedulerContext实例;

(9)Calendar:

一个Trigger可以和多个Calendar关联,以排除或包含某些时间点。
比如某个任务希望放假时间不执行。

(10)监听器:

JobListener,TriggerListener,SchedulerListener;分别对Job,
Trigger,Scheduler的事件进行监听,包括scheduler一运行起来的时
候,或者在执行任务的时候,或终止的时候进行监听,监听的时候加入一些
自定义的某些逻辑,比如打印日志信息。

二、第一个Quartz程序

需求:让任务每2秒打印一次helloworld

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hcx.demo</groupId>
    <artifactId>HelloQuartz</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.3</version>
        </dependency>

    </dependencies>

</project>

任务类:

package com.hcx.HelloQuartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by HCX on 2017/9/6.
 * 自定义任务
 */
public class HelloJob implements Job {

    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //打印当前的执行时间,格式为:2017-09-06 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("当前的时间为(HelloJob):" + sf.format(date));
        //编写具体的业务逻辑
        System.out.println("Hello Job!");
    }

}

任务调度类:

package com.hcx.HelloQuartz;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by HCX on 2017/9/6.
 */
public class HelloScheduler {

    public static void main(String[] args) throws SchedulerException {
        /**
         * JobDetail:用来绑定Job,并且在job执行的时候携带一些执行的信息
         */
        //创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myJob","group1").build();

        /**
         * Trigger:用来触发job去执行的,包括定义了什么时候去执行,
         * 第一次执行,是否会一直重复地执行下去,执行几次等
         */
        //创建一个Trigger实例,定义该job立即执行,并且每隔2秒钟重复执行一次,直到程序停止
        /**
         * trigger通过builder模式来创建,TriggerBuilder.newTrigger()
         * withIdentity():定义一个标识符,定义了组
         * startNow():定义现在开始执行,
         * withSchedule(SimpleScheduleBuilder.simpleSchedule():withSchedule也是builder模式创建
         *.withIntervalInSeconds(2).repeatForever()):定义了执行频度:每2秒钟执行一次,不间断地重复执行
         * build():创建trigger
         */
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myTrigger","group1").startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(2).repeatForever()).build();

        //创建scheduler实例:
        /**
         * scheduler区别于trigger和jobDetail,是通过factory模式创建的
         */
        //创建一个ScheduleFactory
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.start();

        //打印当前时间
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("当前的时间为(HelloScheduler):" + sf.format(date));

        //需要将jobDetail和trigger传进去,并将jobDetail和trigger绑定在一起。
        scheduler.scheduleJob(jobDetail,trigger);

    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容