标签:uart schedule tac esc 任务定义 自己 编程 RKE www
直接看官网吧,Quartz官网
什么是 Quartz Job Scheduling Library?
Quartz是一个功能丰富的开源任务调度库,几乎可以集成在任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数十,数百甚至数万个任务; 将任务定义为标准Java组件的任务,这些组件可以执行几乎任何可以编程的程序。Quartz Scheduler包含许多企业级功能,例如支持JTA事务和集群。
下载地址:http://www.quartz-scheduler.org/downloads/
官网终最新已经是version:2.4.0的版本了,另外需要提醒的是1.x和2.x的版本差别挺大的,学习和使用主要是使用2.x的版本
我们选择2.4.0的版本进行下载,我们主要是用其Jar包
第一个c3p0的依赖,是个数据库连接池,本次案例用不上。
使用idea新建一个普通的java工程即可,做一个简单的案例,这里就是孤单的使用Quartz,没有与Spring做整合。
直接上代码:
package com.helius.job;
import com.helius.service.MeetingService;
import org.quartz.*;
import java.util.List;
/**
* @Author Helius
* @Create 2019-08-18-20:48
*/
public class PlanJob implements Job {
MeetingService meetingService = new MeetingService();
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
TriggerKey triggerKey = jobExecutionContext.getTrigger().getKey();// 这个其实就是TestQuartz类的withIdentity方法中定义的属性
JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
System.out.println(triggerKey + "\t" + jobKey);//这句对应控制台输出的group1.meeting trigger group1.meeting job
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
List infos = (List) jobDataMap.get("infos");
System.out.println(infos);
// 存放计划执行的任务
meetingService.calClassMeeting();
}
}
package com.helius.service;
/** * @Author Helius
* @Create 2019-08-18-20:46
*/
// 这个为我们具体要执行的任务
public class MeetingService {
public void calClassMeeting() {
System.out.println("需要提醒的任务(召开会议.....)");
}
}
package com.helius.test;
import com.helius.job.PlanJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.ParseException;
import java.util.Arrays;
import java.util.List;
/**
* @Author Helius
* @Create 2019-08-18-20:51
*/
public class TestQuartz {
public static void main(String[] args) throws SchedulerException, InterruptedException, ParseException {
// PlanJob
JobBuilder jobBuilder = JobBuilder.newJob(PlanJob.class);
// 产生实际使用的Job
JobDetail jobDetail = jobBuilder.withIdentity("meeting job", "group1").build();
// 向Job的execute()中传入一些参数
JobDataMap jobDataMap = jobDetail.getJobDataMap();
List<String> names = Arrays.asList(new String[]{"zs","ls","ww"});
jobDataMap.put("infos",names);
// 下面这几句关于TriggerBuilder可以采用方法链的写法更简洁,因为返回的是当前对象this
// 触发器:时间规则,,依赖两个对象(TriggerBuilder,Scheduel)
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder = triggerBuilder.withIdentity("meeting trigger", "group1");
triggerBuilder.startNow();//当满足条件时执行
/* SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date start = sdf.parse("2019-8-18 21:20:45");
Date end = sdf.parse("2019-8-18 21:20:55");
triggerBuilder.startAt(start);
triggerBuilder.endAt(end);*/
//ScheduleBuilder:定执行的周期
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
scheduleBuilder.withIntervalInSeconds(1);// 每隔一秒执行一次
scheduleBuilder.withRepeatCount(2);//执行2次
// 产生触发器
SimpleTrigger trigger = triggerBuilder.withSchedule(scheduleBuilder).build();
// 调度器(工厂产生调度器)
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
// 产生调度器
Scheduler scheduler = schedulerFactory.getScheduler();
// 产生一个默认的调度器,与上面两句代码等价
//Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
// 通过调度器 将 任务 和 触发器 一一对应
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
Thread.sleep(10000); // 休眠10秒,保证关闭前代码任务执行完了
// 关闭方法
scheduler.shutdown(); // 如果不shutdown,应用不会停止,因为还有活动的线程
}
}
打印下结果
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
就是这么简单,先把代码跑起来,再来具体学习。
先看PlanJob类,实现了Job类,这是Quartz中的类,表示这是一任务,实现这个Job唯一的抽象方法execute,当我们看示例代码时,我们可以只关注meetingService.calClassMeeting();
这一句任务的执行代码即可,
方法execute有一个参数:JobExecutionContext jobExecutionContext
即Job执行的上下文对象,当然听这个名字,就能知道通过这个对象,我们能拿到很多我们可能在任务执行的时候需要的信息。
考虑这样一个需求,我们的任务是提醒开会,那提醒哪些人需要开会呢,好像在打印的过程中,我们输出了
[zs, ls, ww]
这样一行信息,我们怎么加进去呢,
TestQuartz类中有这样的代码
// 向Job的execute()中传入一些参数
JobDataMap jobDataMap = jobDetail.getJobDataMap();
List<String> names = Arrays.asList(new String[]{"zs","ls","ww"});
jobDataMap.put("infos",names);
然后我们在PlanJob中可以动态的拿到这些信息
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
List infos = (List) jobDataMap.get("infos");
System.out.println(infos);
其实还有另外一种写法,通过usingJobData这个方法,这里采用了链式写法, 建议自己写一下。
//定义一个JobDetail
JobDetail job = newJob(MailJob.class) //指定干活的类MailJob
.withIdentity("mailjob1", "mailgroup") //定义任务名称和分组
.usingJobData("email", "admin@10086.com") //定义属性
.build();
再来看PlanJob类中的
TriggerKey triggerKey = jobExecutionContext.getTrigger().getKey();
JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
System.out.println(triggerKey + "\t" + jobKey);
这个就对印我们输出行中的,毕竟任务可能有很多,所以我们需要给他们分个组,加个id,即加个唯一标志符。
group1.meeting trigger group1.meeting job
剩下的一些代码,在注释里面已经写的很详细了,不再细讲了
Quartz有这样一个特性,就是在第一个任务未执行完,第二个任务便会继续开始,我们来测试下,我们改写一下PlanJob类,
public class PlanJob implements Job {
MeetingService meetingService = new MeetingService();
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
TriggerKey triggerKey = jobExecutionContext.getTrigger().getKey();
JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
System.out.println(triggerKey + "\t" + jobKey);
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
List infos = (List) jobDataMap.get("infos");
System.out.println(infos);
// 存放计划执行的任务
meetingService.calClassMeeting();
try {
Thread.sleep(5000); // 休眠5秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行完了");
}
}
观察控制台:
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
执行完了
执行完了
执行完了
在第一个任务执行后,中途会有5秒的休眠时间,但是第二个任务依旧开始了
默认的情况下,无论上一次任务是否结束或者完成,只要规定的时间到了,那么下一次就开始。
有时候会做长时间的任务,比如数据库备份,这个时候就希望上一次备份成功结束之后,才开始下一次备份,即便是规定时间到了,也不能开始,因为这样很有可能造成 数据库被锁死 (几个线程同时备份数据库,引发无法预计的混乱)。
那么在这种情况下,给数据库备份任务增加一个注解就好了: @DisallowConcurrentExecution
给PlanJob类加上注解后,
再次运行TestQuartz
类,观察控制台输出结果:
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
执行完了
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
执行完了
group1.meeting trigger group1.meeting job
[zs, ls, ww]
需要提醒的任务(召开会议.....)
执行完了
和我们预计的一样。
Tips:Quartz的官网的文档很详细,例子也很多,英文也使用的很简单,值得详细阅读。
好像还有很多没讲完,睡觉睡觉,加油加油!!!
标签:uart schedule tac esc 任务定义 自己 编程 RKE www
原文地址:https://www.cnblogs.com/heliusKing/p/11374520.html