文章目录
Java定时任务
数据结构–堆
堆
插入元素
删除堆顶元素
Quartz任务调度
一、Quartz概念
二、Quartz运行环境
三、Quartz设计模式
四、Quartz学习的核心概念
五、Quartz的体系结构
六、Quartz的几个常用API
七、Quartz使用
1.入门案例
2.Job和JobDetail介绍
3.JobExecutionContext介绍
4.JobDataMap介绍
5.有状态的Job和无状态的Job
6.Trigger介绍
7.SimpleTrigger触发器
8.CronTrigger触发器
9.配置资源SchedulerFactory
10.Quartz.properties配置文件介绍
11.Quartz监听器
a.概念
b.JobListener
c.TriggerListener
d.SchedulerListener
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