java程序的定时调度框架_Java定时任务调度框架Quartz入门详解案例

一、什么是Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

持久性作业 - 就是保持调度定时的状态;

作业管理 - 对调度作业进行有效的管理;

拿火车票购票来说,当你下单后,后台就会插入一条待支付的task(job),一般是30分钟,超过30min后就会执行这个job,去判断你是否支付,未支付就会取消此次订单;当你支付完成之后,后台拿到支付回调后就会再插入一条待消费的task(job),Job触发日期为火车票上的出发日期,超过这个时间就会执行这个job,判断是否使用等。

二、Quartz核心概念

1.任务/作业(Task/Job)

位于org.quartz.Job的接口,是quartz中的核心任务接口,要实现自定义的定时任务(就是我们要执行的业务动作/作业)只需要实现此接口。

dc260188b3404462eb15af16d2f4f691.png

2.触发器(Trigger)

位于org.quartz.Trigger,触发器用来告诉调度程序作业什么时候触发,也就是我们要设置任务触发的条件。quartz提供了5种触发器类型,但两个最常用的SimpleTrigger和CronTrigger。

五种类型的Trigger(触发器):

SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar。

e9f327fef4f95b9bcf83245aa734e4e6.png

3.调度器(Schedule)

来自org.quartz.Schedule是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度器负责执行作业,当他们的相关联的触发器触发时(当他们的预定时间到达时)。不难看出功能就是将任务job与触发器Trigger作业结合起来。

6632332fc26f4fd2166da72c12106d42.png

4.任务执行时上下文(JobExecutionContext)

位于org.quartz.JobExecutionContext的类,是任务在执行时quartz注入的对象,用于保存任务的详细信息(比如触发器,调度器,工作详情,任务入参等),我们可以通过此对象得到运行时的任务数据,也可以接受动态参数。

主要有以下方法:

14230049.html

5.任务详情(JobDetail)

位于org.quartz.JobDetail,用来绑定job,为job提供一些属性:

name:唯一标识

group:分组标识

jobClass:具体任务

jobDataMap:任务入参

为什么设计成JobDetail + Job,不直接使用Job?

JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。

这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

三、案例demo实现

1.定义自定义任务,继承job接口

public class MyJob implements Job {

private final Logger log = LoggerFactory.getLogger(MyJob.class);

@Override

public void execute(JobExecutionContext context) throws JobExecutionException {

log.error("定时任务:发送一次消息,时间={"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))+

"}");

log.error("请求参数:{name="+context..getJobDetail().getJobDataMap().get("name").toString()+",sign="+context.getJobDetail().getJobDataMap().get("sign").toString()+"}");

}

}

2.创建demo

public class Demo {

public static void main(String[] args) throws SchedulerException {

//1.初始化调度器工厂

SchedulerFactory schedulerFactory = new StdSchedulerFactory();

//2.获取调度器

Scheduler scheduler = schedulerFactory.getScheduler();

//3.创建任务实例

JobDetail jobDetail = newJob(MyJob.class)//一个静态builder方法

.withDescription("这是我的入门实例Job")//任务备注

.withIdentity("demoJob","demoGroup")//标识与分组

.usingJobData("name","张三")//传入参数

.usingJobData("sign","abcdefg")

.build();

//4.创建任务触发器

Trigger trigger = TriggerBuilder.newTrigger()

.withIdentity("demoJob","demoGroup")

/*.withSchedule(SimpleScheduleBuilder.simpleSchedule()//简单任务触发器

.withIntervalInSeconds(10)//每10秒执行一次

.withRepeatCount(5)//执行5次

)*/

.withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?"))//定时触发调度器

.startAt(new Date(System.currentTimeMillis()+10))//十秒后开始执行任务

.build();

//5.将任务和触发器注入到quartz中

scheduler.scheduleJob(jobDetail,trigger);

//6.启动任务

scheduler.start();

}

}

3.运行测试,注意运行就会触发一次任务,然后每5秒触发一次

ff11a8903551dcd00c70914f1c947ba2.png

四、CronExpression表达式详解

通过使用不难发现任务执行的条件才是我们最关心的,quartz支持Cron表达式来定义触发器规则。

“*”字符被用来指定所有的值。如:”“在分钟的字段域里表示“每分钟”。

“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。

“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”.

“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。

“L”字符指定在月或者星期中的某天(最后一天)。即“Last ”的缩写。但是在星期和月中“L”表示不同的意思,如:在月子段中“L”指月份的最后一天-1月31日,2月28日,如果在星期字段中则简单的表示为“7”或者“SAT”。如果在星期字段中在某个value值得后面,则表示“某月的最后一个星期value”,如“6L”表示某月的最后一个星期五。

“W”字符只能用在月份字段中,该字段指定了离指定日期最近的那个星期日。

“#”字符只能用在星期字段,该字段指定了第几个星期value在某月中

结合示例更加清晰:

015867f0719fc1de2b6b9f106ca0f1cc.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值