文章目录
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 的原理就会变得简单了。
-
Job
表示一个工作,要执行的具体内容。此接口中只有一个方法,如下:
void execute(JobExecutionContext context)
-
JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
-
Trigger 代表一个调度参数的配置,什么时候去调。
-
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
、``TriggerListener、
SchedulerListener`监听器,用于对组件的监听
七、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有一些不同的触发器类型,不过,用得最多的是SimpleTrigger
和CronTrigger
(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监听器主要有JobListener
、TriggerListener
、SchedulerListener
三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,两者的区别在于:
全局监听器能够接收到所有的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();