Quartz定时任务基础学习

Quartz基础笔记

前言

1、什么是Quartz

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

2、Quartz的运行环境是什么?

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

3、Quartz的运行环境

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

一、Quartz的核心概念

学习Quartz之前我们需要了解几个概念:

  1. Job(任务)

我们可以把这里Job理解为一个进程下的多个线程,Job表示一个工作,也就是执行具体业务逻辑的一个类,它里面就一个方法execuate

void execute(JobExecutionContext context) 
  1. JobDeatil(可执行的任务调度)

这里的JobDetail我么可以看作是一个封装的Job类,只有将具体的业务Job封装成JobDetail才可以被Quartz识别并调用。另外 JobDetail 还包含了这个任务调度的方案和策略。

  1. Trigger(触发器)

代表一个调度参数的配置,即我们时候去调用在Trigger里设置

  1. Scheduler(调度容器)

是一个整合JobDetail和Trigger的容器,一个Scheduler里可以放置多个JobDetail和Trigger

在这里插入图片描述

1.1 案例DEMO

由上图我们可以清楚的了解到,一个jobDetail是由JobBuilder创建,一个Trigger是由TriggerBuilder创建。而JobDetail和Trigger里可以创建对应的JobDataMap,往Map里加一些参数,供execuate方法里获取到对应的JobDataMap根据键获取到对应的属性值。

【引入依赖】

<dependencies>
		<!-- Quartz核心包 -->
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.3.2</version>
		</dependency>

		<!-- QUartz工具包 -->
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>2.3.2</version>
		</dependency>
		
		<!-- Log4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
</dependencies>

【分析步骤】

  1. 由stdSchedulerFactory创建一个Scheduler
// 创建一个scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

可以通过scheduler获取到context(这里的context就是execuate里面的参数JobExecutionContext context),从而往里面设置一些属性

  1. 由scheduler创建对应的JobDetail和Trigger
// 创建JobDetail 由JobBuilder创建
		JobDetail job = JobBuilder.newJob(MyJob.class)
									.withIdentity("myjob", "mygroup")
									.usingJobData("j1", "jv1")
									.build();
		job.getJobDataMap().put("j2", "jv2");
		
		// 创建Trigger 由TriggerBuilder创建
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1")
                .usingJobData("t1", "tv1")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3)
                        .repeatForever()).build();
        trigger.getJobDataMap().put("t2", "tv2");

由scheduler创建的JobDetail和Trigger都支持链式编程,而且创建出来的JobDetail和Trigger都必须要添加一个属性withIdentity(String key,String value)

  1. 由scheduler添加创建出来的JobDetail和Trigger
scheduler.scheduleJob(JobDetail,Trigger);
  1. 启动Scheduler
scheduler.start();

在这里插入图片描述

如上图所示,Trigger每隔2s调用一次JobDetail执行Job所实现的Job真正的业务

上述示例是一个SimpleScheduler调度的。

1.2 Quartz核心API

Scheduler:与调度程序交互的接口

Job:你想要调度器执行的任务的组件所实现的接口

JobDetail:用于定义任务作业的示例

Trigger:触发器,用于定时调用JobDetail所封装的Job的组件

JobBuilder:构建JobDetail的示例的

TriggerBuilder:用于构建Trigger的示例的

1.3 Job和obDetail介绍

  • Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execuate方法,类似JDK的TimeTask类的run方法,在里面编写执行业务逻辑。
  • Job实例在Quartz中的生命周期,每次调度器执行完毕,他在调用execuate方法之前都会先创建一个新的Job实例,把原来的释放,释放的实力会被垃圾回收机制收回。
  • JobDetail:jobDetail实力提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定的Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
  • jobDetail重要属性:name,group,jobClass,jobDataMap

1.4 JobExecuateContext介绍

  • 当Scheduler调用一个Job的时候,就会将JobExecuateContext传递给Job的execuate()方法。
  • Job能通过JobExecuateContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

1.5 JobDataMap介绍

(1)使用Map获取

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

1.6 有状态的Job和无状态的Job

通过@PersistJobDataAfterExecuation注解使用

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

1.7 Trigger的详解

和Job一样,Trigger也和Trigger一样很好使用,但是Trigger有很多的类型,这里只详细学习一下SimpleTriggerCornTrigger两个核心的Trigger类型

1.7.1 Trigger的公共属性

注意:不管什么类型的Trgger,都有一个必须的属性:TriggerKey,用于唯一标识一个Trigger

除了TriggerKey以外,trigger还有一些公共属性。

  1. jobKey:当Trigger被触发的时候,执行的是哪一个Job
  2. startTime:开始触发的时间,该属性的值是一个java.util.Date类型的
  3. endTime:Trigger失效的时间点,比如说一个每个月的第五天执行的Trigger,假如他的endTime设置成7月1日,那么他最后一次执行的时间就是6月5日

1.7.2 Trigger的公共属性🔥🔥

SimpleTrigger可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。比如,你有一个trigger,你可以设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,并且每隔2秒触发一次,一共重复5次。


SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔。

  1. 开始时间:
  2. 结束时间
  3. 重复次数:可以是0、正整数,以及常量SimpleTrigger.REPEAT_INDEFINITELY
  4. 重复的间隔:必须是0,正整数
public class MainHelloTrigger {

	public static void main(String[] args) throws Exception {
		// 任务调度器 StdSchedulerFactory
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		// 设置任务的开始时间
		Date startDate = new Date();
		// 延迟3s执行
		startDate.setTime(startDate.getTime()+3000);
		// 设置任务的结束时间
		Date endDate = new Date();
		endDate.setTime(endDate.getTime()+10000);
		// 调度任务实例
		JobDetail jobDetail = JobBuilder.newJob(HelloJobTrigger.class) 		// 加载任务类的实例
				.withIdentity("helloJob", "HelloJobGroup")			// 参数一:任务的名称(唯一实例);参数二:任务组的名称
				.build();
		
		// 触发器Trigger
		Trigger trigger = TriggerBuilder.newTrigger() 				// 创建一个触发器
				.withIdentity("HelloTrigger", "HelloTiggerGroup") 	// 参数一:触发器的名称;参数二:触发器的群组名
//				.startNow() // 马上启动触发器 只执行一次
//				.startAt(startDate) // 设置任务的开始时间
				.endAt(endDate)				.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) // 创建一个每5s重复执行一次的简单调度器 
				.build();
	
		// 获取触发器的名称以及组的名称 同理Job  如果不指定组名,按默认去执行  任务/触发器的名称必须要指明
		
		// 让调度器Scheduler关联触发器和任务
		scheduler.scheduleJob(jobDetail,trigger);
		// 启动scheduler调度任务
		scheduler.start();
	}
}

1.8 CronTrigger

CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。

使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。

即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

二、Quartz配置

2.1配置、资源SchedularFactory

Quartz以模块方式架构,因此,要是他运行,几个组件必须很好二点聚合在一起,幸运的是,已经有了一些现存的助手可以完成这些工作。

所有的Schedular实例都是由SchedularFactory创建。

Quartz的三个核心概念,调度器,任务,触发器。三者之间的关系是:

在这里插入图片描述

大家都知道,一个作业,比较重要的三个参数就是Scheduler,jobDetail,Trigger;而Trigger对于JOB而言就是好比一个驱动器;没有触发器来定时驱动作业,作业就无法运行;对于JobDetail而言,一个Job可以对应多个Trigger

创建Scheduler的方式有两种:

方式一:

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

方式二:

SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();

2.2、Quartz.properties

默认路径:quartz.2.3.0中的org.quartz中的quartz.properties

在这里插入图片描述

组成部分:

  • 调度器属性

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

org.quartz.scheduler.instanceId:属性和前者一样,允许任何字符串,但是这个值必须要在所有的调度器实例中是唯一的,尤其是在一个集群的环境中。作为唯一的key。

  • 线程池属性

threadCount

处理Job的线程数目,至少为1,但是最多的话最好不要超过100,再多台机器上设置值超过100的话,会显得相当不适用。特别是在Job执行时间较长的情况下。

  • threadPriority

现成的优先级,优先级高的线程优先得到执行。最小的1;其次最大的是10。默认是5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@WAT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值