Quartz任务调度

Java定时任务

数据结构–堆

堆是一种特殊的树,只要满足下面两个条件,它就是一个堆:

(1)堆是一颗完全二叉树(除最后一层以外,剩下的层达到最大节点)

(2)堆种某个节点的值总是不大于(或不小于)其父节点的值

其中,我们把根节点最大的堆叫做大顶堆,根节点最小的堆叫做小顶堆

满二叉树:所有层都达到最大节点数 1、2、4、8

在这里插入图片描述

完成二叉树:除了最后一层外其他层都达到最大节点数,且最后一层节点都靠左排列(1、2、4、2)

在这里插入图片描述

完全二叉树最适合用数组做存储,因为它的节点都是紧凑的,且只有最后一层节点数不满

在这里插入图片描述

为什么下标0的位置不存在元素呢?

这是因为这样存储我们可以很方便地找到父节点:下标/2,比如,4的节点即4/2=2,5的父节点即5/2=2。

堆也是一颗完全二叉树,但是它的元素必须满足每个节点的值都不大于(或不小于)其父节点的值。比如下面的堆:

在这里插入图片描述

数组存储结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

这时候我们要找8的父节点就拿8的位置下标 5/2=2,也就是5这个节点的位置。这也是为了我们后面堆化。

插入元素

规律:插入尾部,然后上浮

往堆中插入一个元素后,我们需要继续满足堆的两个特性,即:

(1)堆是 一颗完全二叉树

(2)堆中某个节点的值总是不大于(或不小于)其父节点的值。

为了满足条件(1),所以我们把元素插入到最后一层最后一个节点往后一位的位置,但是插入之后可能不再满足条件(2)了,所以这时我们需要堆化。

比如,上面那个堆我们需要插入元素2,我们把它放在9后面,这时不满足条件(2)了,我们就需要堆化。(这是一个小顶堆)

在这里插入图片描述

在完全二叉树中,插入的节点与它的父节点相比,如果比父节点小,就交换它们的位置,再往上和父节点相比,如果还比父节点小,就再次交换位置,直到比父节点大为止。

在数组中,插入的节点与n/2位置的节点相比,如果比n/2位置的节点小,就交换它们的位置,再往前与n/4位置的节点相比,如果比n/4位置的节点小,再次交换位置,直到比n/(2^x)位置的节点大为止。

这就是插入元素时进行的堆化,也叫自下而上的堆化。

从插入元素的过程中,我们知道每次与n/(2^x)的为止进行比较,所以,插入元素的时间复杂度为O(log n)。

删除堆顶元素

将尾部(最大的元素)元素放到堆顶,然后下沉

小顶堆中堆顶存储的是最小的元素,这时候我们把它删除会怎样呢?

删除了堆顶元素后,要使得还满足堆的两个特性,首先,我们可以把最后一个元素移到根节点的位置,这时候就会满足条件(1),之后就是使它满足条件(2),就需要堆化了。

在这里插入图片描述

在完全二叉树中,把最后一个节点放到堆顶,然后与左右子节点中最小的交换位置(因为是小堆顶),依次往下,直到其比左右子节点都小为止。

在数组中,把最后一个元素移到下标为1的位置,然后与下标为2和3的位置对比,发现8比2大,且2是2和3之间最小的,所以与2交换位置,然后再与4和5的位置对比,发现8比5大,且5是5和7之间最小的,所以与5交换位置,没有左右子节点了,堆化结束。

这就是删除元素时进行的堆化,也叫自上而下的堆化。

从删除元素的过程,我们知道把最后一个元素拿到根节点后,每次与2n和(2n+1)位置的元素比较,取其小者,所以删除元素的时间复杂度也为O(log n)。

Quartz任务调度

一、Quartz概念

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目。

Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。

Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。

Quartz 允许程序开发人员根据时间的间隔来调度作业。

Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。

核心概念

我们需要明白 Quartz 的几个核心概念,这样理解起 Quartz 的原理就会变得简单了。

  1. Job

    表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:

    void execute(JobExecutionContext context) 
    
  2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

  3. Trigger 代表一个调度参数的配置,什么时候去调。

  4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

二、Quartz运行环境

  • Quartz 可以运行嵌入在另一个独立式应用程序。
  • Quartz 可以在应用程序服务器(或 servlet 容器)内被实例化,并且参与 XA 事务。
  • Quartz 可以作为一个独立的程序运行(其自己的 Java 虚拟机内),可以通过 RMI 使用。
  • Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行。

三、Quartz设计模式

  • Builder模式
  • Factory模式
  • 组件模式
  • 链式编程

四、Quartz学习的核心概念

  • 任务Job

    Job就是你想要实现的任务类,每一个Job必须实现org.quartz.Job接口,且只需要实现接口定义的execute()方法

  • 触发器Trigger

    Trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点会执行该任务。Trigger主要包含两种SimpleTrigger和CronTrigger两种。关于两者的区别的使用场景,将在下面讲解

  • 调度器Scheduler

    Scheduler为任务的调度器,它会将任务Job和触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job

五、Quartz的体系结构

在这里插入图片描述

六、Quartz的几个常用API

以下是Quartz编程API几个重要接口,也是Quartz的重要组件

  • Scheduler用于与调度程序交互的主程序接口。

    Scheduler调度程序(任务执行计划表),只有安排进执行计划的任务Job(通过scheduler.scheduleJob方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发Trigger),该任务才会执行

  • Job我们预先定义的希望在未来时间能被调度程序执行的任务类,我们可以自定义

  • JobDetail 使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建的

  • JobDataMap 可以包含不限量的(序列化)数据对象,在job实例执行的时候,可以使用其中的数据,JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法

  • Trigger 触发器,Trigger对象是用来触发执行任务Job的。当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件。表明任务在什么时候会执行。定义了一个已经被安排的任务将会在什么时候执行的时间条件,比如每2秒执行一次

  • JobBUilder用于声明一个任务实例,也可以定义关于该任务的详情,比如任务名、组名等,这个声明的实例将会作为一个实际执行的任务。

  • TriggerBuilder 触发器创建器,用户创建触发器Trigger实例

  • JobListener、``TriggerListenerSchedulerListener`监听器,用于对组件的监听

七、Quartz使用

=注意:如果定时任务的开始时间小于当前时间,则定时任务立即执行=

1.入门案例

引入maven依赖

<!-- 核心包 -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version>
</dependency>

<!-- 工具包 -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.3.2</version>
</dependency>

案例:

开发任务类

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

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
	@DisallowConcurrentExecution:将该注解加到job类上,告诉Quartz不要并发地执行同一个JobDetail实例
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution 
public class TaskJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println("time = " + time);
    }
}

测试

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class test {

    public static void main(String[] args) throws SchedulerException {
        //获取调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        //获取任务实例
        JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
                .withIdentity("job1", "group1")//参数1:任务名(唯一实例),参数2:组名
                .build();

        //获取触发器
        SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
                .startNow()//马上启动触发器
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever())
                .build();

        //让调度器关联任务和触发器
        scheduler.scheduleJob(jobDetail,simpleTrigger);

        //启动
        scheduler.start();
    }
}
2.Job和JobDetail介绍
  • Job :工作任务调度的接口,任务类需要实现该接口。该接口中定义execute方法,类似JDK提供的TimeTask类的run方法。在里面编写任务执行的业务逻辑

  • Job实例在Quartz中的生命周期:每次调度器执行Job时,它在调用execute方法前会创建一个新的Job实例,当调用完毕后,关联的Job对象实例会被释放,释放的实例会被垃圾回收机制回收。

  • JobDetail :jobDetail为job实例提供了许多设置属性,以及jobDataMap成员变量属性,它用来存储特定job实例的状态信息,调度器需要借助jobDetail对象来添加job实例

  • JobDetail重要属性:name、group、jobClass、jobDataMap

    //获取任务名,必填
    String name = jobDetail.getKey().getName();
    //获取任务组名,注意:如果没有指定组名,默认为DEFAULT
    String groupName = jobDetail.getKey().getGroup();
    //获取任务类
    String className = jobDetail.getJobClass().getName();
    
3.JobExecutionContext介绍
  • 当Scheduler调用一个Job,就会将jobExecutionContext传递给job的execute()方法
  • job能通过jobExecutionContext对象访问到Quartz运行时候的环境以及job本身的明细数据
4.JobDataMap介绍

1)使用Map获取

  • 在进行任务调度时,JobDataMap存储在jobExceutionContext中,非常方便获取
  • JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时,这些参数对象会传递给它
  • JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法用来存取基本数据类型

存:

位置:创建时一并加入

JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("message","任务的jobDataMap数据");

//获取任务实例
JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
    .withIdentity("job1", "group1")//参数1:任务名(唯一实例),参数2:组名
    .usingJobData(jobDataMap)
    .build();

JobDataMap triggerByJobDataMap = new JobDataMap();
jobDataMap.put("message","触发器的jobDataMap数据");
//获取触发器
SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
    .startNow()//马上启动触发器
    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever())
    .usingJobData(triggerByJobDataMap)
    .build();

取:

位置:任务类中的execute方法中


JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
String message = jobDataMap.getString("message");

JobDataMap triggerJobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
String triggerMessage = triggerJobDataMap.getString("message");

2)Job实现类中添加setter方法对应JobDataMap的键值,Quartz框架默认的JobFactory实现类在初始化job实例对象时会自动地调用这些setter方法,把key对应的值赋值给变量

private String message;

public void setMessage(String message){
    this.message = message;
}

注意:如果遇到同名的key,Trigger中的.usingJobDataMap()方法传入的map中的key所对应的值会覆盖jobDetail中的.usingJobDataMap()方法传入的map中的key对应的值(简单理解:如果Trigger和JobDetail的JobDataMap有相同key,使用成员变量获取值,会以Trigger优先)

5.有状态的Job和无状态的Job

@PersistJobDataAfterExecution注解的使用

有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态Job每次调用时都会创建一个新的JobDataMap。

注解的作用就是 可以让在本次启动中 JobDataMap中的一些信息共享使用。例如:累加器等

6.Trigger介绍

在这里插入图片描述

Quartz有一些不同的触发器类型,不过,用得最多的是SimpleTriggerCronTrigger

(1)jobKey

表示job实例的标识,触发器被触发时,该指定的job实例会被执行。

Trigger trigger = jobExecutionContext.getTrigger();
JobKey jobKey = trigger.getJobKey();
String jobKeyName = jobKey.getName();
String group = jobKey.getGroup();

(2)startTime

标识触发器的时间表,第一次开始被触发的时间,它的数据类型是java.util.Date。

Trigger trigger = jobExecutionContext.getTrigger();
Date startTime = trigger.getStartTime();

(3)endTime

指定触发器终止被触发的时间,它的数据类型是java.util.Date。

Trigger trigger = jobExecutionContext.getTrigger();
Date endTime = trigger.getEndTime();

注意:如果是创建job实例时,使用了startNow()方法,立即执行,则无法获取开始时间和结束时间。如果需要获取两个变量值,则必须都设置,只设置其中一个获取时将会报错。

7.SimpleTrigger触发器

SimpleTrigger对于设置和使用是最为简单的一种QuartzTrigger。

它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的Job所设计的。

案例:在指定的时间间隔内多次执行任务 任务:每5秒执行一次,且执行3次

上重要代码:
//获取触发器
SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger1", "triggerGroup1")//参数1:任务名(唯一实例),参数2:组名
    .startNow()//马上启动触发器
    //每5秒执行一次,且执行3次 扩展:withRepeatCount方法参数从0开始
    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(2))
    .build();

注意点:

  • SimpleTrigger的属性有:开始时间、结束时间、重复执行次数和重复执行的时间间隔
  • 重复执行次数的属性的值可以为0、正整数或常量(例如:SimpleTrigger.REPEAT_INDEFINITELY)
  • 重复执行的时间间隔属性值必须大于0或长整数的正整数,时间间隔有多个方法,常用有毫秒(withIntervalInMilliseconds)、秒(withIntervalInSeconds)、分(withIntervalInMinutes)、时(withIntervalInHours)为单位的时间间隔
  • 如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒触发一次直到指定的结束时间的Trigger,而无须去计算从开始到结束的所重复次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性值即可
8.CronTrigger触发器

基于日历的作业调度器,使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的9:30”,又或者“从每个周一、周三、周五的上午9:30到上午10:00之间每隔5分钟”这样日程安排来触发。甚至,像SimpleTrigger一样,CronTrigger也有一个startTime以指定日程从什么时间开始,也有一个(可选)endTime以指定何时日程不再继续.

(1)Cron Expressions — Cron表达式

Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串,每个子表达式都描述了一个单独的日程细节。这些子表达式用空格分隔。

详细介绍请看:https://blog.csdn.net/zhangruilinmoo/article/details/107205096

9.配置资源SchedulerFactory

Quartz以模块方式构架。所有的Scheduler实例由SchedulerFactory创建
一个Job(任务)可以对应多个Trigger(触发器),而对于Trigger(触发器)而言,一个Tigger对应一个Job(任务)

Scheduler的创建方式

1)StdSchedulerFactory

简介:Quartz默认的SchedulerFactory

执行:

  • 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器

  • 配置参数一般存储在quartz.properties文件中

  • 调用getScheduler方法就能创建和初始化调度器对象

    • SchedulerFactory schedulerFactory = new StdSchedulerFactory();
      Scheduler scheduler = schedulerFactory.getScheduler();
      

用法一:输出调度器开始的时间(重要:使得任务和触发器进行关联)

Date scheduleJob(JobDetail jobDetail,Trigger trigger)

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = scheduler.scheduleJob(job,trigger);
System.out.println("调度器开始的时间 time=" + sdf.format(data));

用法二:启动任务调度

void start();

scheduler.start();

用法三:任务调度挂起,即暂停操作

void standby();

scheduler.standby();

用法四:关闭任务调度

void shutdown()

shutdown(true):表示等待所有正在执行的job执行完毕之后,再关闭Scheduler

shutdown(false):表示直接关闭Scheduler

2)DirectSchedulerFactory(了解)

DirectSchedulerFactory是对SchedulerFactory的直接实现,通过它可以直接构建Scheduler,threadpool等

DirectSchedulerFactory directSchedulerFactory = DirectSchedulerFactory.getInstance();
Scheduler scheduler = directSchedulerFactory.getScheduler();
10.Quartz.properties配置文件介绍

在这里插入图片描述

我们可以在项目的资源下添加quartz.properties文件,去覆盖底层的配置文件

配置介绍

  • 调度器属性

org.quartz.scheduler.instanceName属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。

org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,但这个值必须在所有调度器实例中是唯一的,尤其是在一个集群环境中,作为集群的唯一key。假如想Quartz帮你生成这个值的话,可以设置为AUTO。

  • 线程池属性

org.quartz.threadPool.threadCount:处理job的线程个数,至少为1,但最多的话不要超过100.在多数机器上设置该值超过100的话就会显得相当不实用了,特别是在job执行时间较长得情况下

org.quartz.threadPool.threadPriority:线程得优先级。优先级别高的线程比级别低的线程优先得到执行。最少为1,最大为10,默认为5

org.quartz.threadPool.class:一个实现了org.quartz.sql.ThreadPool接口的类,Quartz自带的线程池实现类是org.quartz.smpl.SimpleThreadPool

备注:简单了解 ,如果需要深入了解,可以找度娘自行查询

11.Quartz监听器
a.概念

Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListenerTriggerListenerSchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,两者的区别在于:

全局监听器能够接收到所有的Job/Triiger的事件通知,

非全局监听器只能接收到在其上注册的job或trigger的事件,不在其上注册的job或trigger则不会进行监听。

b.JobListener

任务调度过程中,与任务job相关的事件包括:job开始要执行的提示,job执行完成的提示。

接口:

package org.quartz;

public interface JobListener {
    /*
    	用于获取该jobListener的名称
    */
    String getName();

    /*
    	Scheduler在JobDetail将要被执行时调用这个方法
    */
    void jobToBeExecuted(JobExecutionContext var1);

    /*
    	Scheduler在JobDetail即将被执行,但又被TriggerListener否决时会调用该方法
    */
    void jobExecutionVetoed(JobExecutionContext var1);

    /*
    	Scheduler在JobDetail被执行之后调用该方法
    */
    void jobWasExecuted(JobExecutionContext var1, JobExecutionException var2);
}

使用步骤:

  • 实现JobListener接口,并按照自身需求实现对应的方法

  • 创建并注册监听器

    都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

    scheduler.scheduleJob(jobDetail,simpleTrigger);
    
    //全局监听器
    scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
    
    //局部监听器,指定jobKey(唯一标识)。在创建job任务类时,通过withIdentity方法添加
    scheduler.getListenerManager().addJobListener(new MyJobListener(), KeyMatcher.keyEquals(JobKey.jobKey("job1", "group1")));
    
    scheduler.start();
    
c.TriggerListener

任务调度过程中,与触发器Trigger相关的事件,包括:触发器触发、触发器未正常触发、触发器完成等。

接口:

package org.quartz;

import org.quartz.Trigger.CompletedExecutionInstruction;

public interface TriggerListener {
    /*
    	用于获取触发器的名称
    */
    String getName();

    /*
    	当与监听器相关的Trigger被触发,job上的execute方法将被执行时,Scheduler就调用该方法
    */
    void triggerFired(Trigger var1, JobExecutionContext var2);

    /*
    	在Trigger触发后,job将要被执行时由Scheduler调用这个方法。TriggerListener给了一个选择去否决job的执行,假如这个方法返回true,这个job将不会为此次Trigger触发而得到执行
    	trur:表示不会执行,false:表示执行
    */
    boolean vetoJobExecution(Trigger var1, JobExecutionContext var2);

    /*
    	在Trigger错过触发时由Scheduler执行
    */
    void triggerMisfired(Trigger var1);

    /*
    	Trigger被触发并且完成job的执行时,执行该方法
    */
    void triggerComplete(Trigger var1, JobExecutionContext var2, CompletedExecutionInstruction var3);
}

使用步骤:

  • 实现TriggerListener接口,并按照自身需求实现对应的方法

  • 创建并注册监听器

    都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

    scheduler.scheduleJob(jobDetail,simpleTrigger);
    
    //全局监听器
    scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), EverythingMatcher.allTriggers());
    
    //局部监听器,指定TriggerKey(唯一标识)。在创建触发器时,通过withIdentity方法添加
    scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "triggerGroup1")));
    
    scheduler.start();
    
d.SchedulerListener

SchedulerListener会在Scheduler的生命周期中关键时间发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger、删除一个job/trigger、scheduler发生严重错误、关闭scheduler等。

public interface SchedulerListener {
    //在调度JobDetail时调用
    void jobScheduled(Trigger var1);
	//当JobDetail未被调度时调用
    void jobUnscheduled(TriggerKey var1);
	//当触发器达到不再触发的条件时调用
    void triggerFinalized(Trigger var1);
	//当一个Trigger被暂停时调用
    void triggerPaused(TriggerKey var1);
	//当一组Trigger被暂停时调用
    void triggersPaused(String var1);
	//当一个Trigger从暂停中恢复时调用
    void triggerResumed(TriggerKey var1);
	//当一组Trigger从暂停中恢复时调用
    void triggersResumed(String var1);
	//当添加了JobDetail时调用。
    void jobAdded(JobDetail var1);
	//当JobDetail被删除时调用。
    void jobDeleted(JobKey var1);
	//在JobDetail暂停时调用。
    void jobPaused(JobKey var1);
	//在暂停一组JobDetail时调用
    void jobsPaused(String var1);
	//当一个JobDetail从暂停中恢复时调用
    void jobResumed(JobKey var1);
	//当一组JobDetail从暂停中恢复时调用
    void jobsResumed(String var1);
	//当调度器内部发生严重错误时,由调度器调用——例如JobStore中的重复失败,或在触发器触发时无法实例化Job实例。
    void schedulerError(String var1, SchedulerException var2);
	//由调度程序调用,以通知侦听器它已移动到待机模式。
    void schedulerInStandbyMode();
	//当scheduler启动完成时调用
    void schedulerStarted();
	//当scheduler启动中时调用
    void schedulerStarting();
	//当scheduler停止时调用
    void schedulerShutdown();
	//关闭序列时调用
    void schedulerShuttingdown();
	//当scheduler中的数据被清除时调用
    void schedulingDataCleared();
}

使用步骤:

  • 实现SchedulerListener接口,并按照自身需求实现对应的方法

  • 创建并注册监听器

    都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

    scheduler.scheduleJob(jobDetail,simpleTrigger);
    
    scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
    
    scheduler.start();
    

Job实例。
void schedulerError(String var1, SchedulerException var2);
//由调度程序调用,以通知侦听器它已移动到待机模式。
void schedulerInStandbyMode();
//当scheduler启动完成时调用
void schedulerStarted();
//当scheduler启动中时调用
void schedulerStarting();
//当scheduler停止时调用
void schedulerShutdown();
//关闭序列时调用
void schedulerShuttingdown();
//当scheduler中的数据被清除时调用
void schedulingDataCleared();
}


使用步骤:

- 实现`SchedulerListener`接口,并按照自身需求实现对应的方法

- 创建并注册监听器

  都是在调度器关联之后,启动之前,添加监听,全局和局部按照自身需求开发

  ```java
  scheduler.scheduleJob(jobDetail,simpleTrigger);
  
  scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
  
  scheduler.start();
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。 Quartz的优势: 1、Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。 2、Quartz是非常灵活的,它让您能够以最“自然”的方式来编写您的项目的代码,实现您所期望的行为 3、Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。 4、Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。 5、可以通过Quartz,封装成自己的分布式任务调度,实现强大的功能,成为自己的产品。6、有很多的互联网公司也都在使用Quartz。比如美团 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度。   课程说明:在我们的日常开发中,各种大型系统的开发少不了任务调度,简单的单机任务调度已经满足不了我们的系统需求,复杂的任务会让程序猿头疼, 所以急需一套专门的框架帮助我们去管理定时任务,并且可以在多台机去执行我们的任务,还要可以管理我们的分布式定时任务。本课程从Quartz框架讲起,由浅到深,从使用到结构分析,再到源码分析,深入解析Quartz、Spring+Quartz,并且会讲解相关原理, 让大家充分的理解这个框架和框架的设计思想。由于互联网的复杂性,为了满足我们特定的需求,需要对Spring+Quartz进行二次开发,整个二次开发过程都会进行讲解。Spring被用在了越来越多的项目中, Quartz也被公认为是比较好用的定时设置工具,学完这个课程后,不仅仅可以熟练掌握分布式定时任务,还可以深入理解大型框架的设计思想。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值