最近须要写一个天天定点自动执行的定时任务,对于之前本身写小项目,可能会选择java自带的Timer类,可是对于公司中的项目,Timer类实现定时任务只能有一个后台线程执行任务,而且只能让程序按照某个频度执行,并不能在指定时间点执行。同时因为通常大型项目会有多个job分别须要在不一样的时间点自动执行,单线程的Timer知足不了需求。而任务调度框架Quartz恰好知足这些需求,我是实习公司的项目中就已经配置好了这个框架,在使用的时候了解了这个quartz,现总结以下。html
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,彻底由Java开发,能够用来执行定时任务,相似于java.util.Timer。可是相较于Timer, Quartz增长了不少功能:
持久性做业 - 就是保持调度定时的状态;
做业管理 - 对调度做业进行有效的管理;
复制代码
quartz主要包括三个部分的模块,定时任务Job、触发器Trigger、调度器Scheduler。
简单的流程就是:调度器根据触发器来执行任务。java
//预约义Job接口--pom.xml须要加载依赖的包
public interface Job {
void execute(JobExecutionContext var1) throws JobExecutionException;
}
//任务逻辑经过实现Job接口,而且重写execute方法,将须要执行的逻辑实现写在execute函数中
public class TestJob implements Job {
/**把要执行的操做,写在execute方法中 */
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("I can do something...");
System.out.println(sdf.format(new Date()));
}
}
参考:https://juejin.im/post/5a0c08c5f265da4335624c8f
//1. 建立一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
JobDetail jobDetail = JobBuilder.newJob(QuartzOrderReturn.class)// 定义Job类为QuartzOrderReturn类,这是真正的执行逻辑所在
.withIdentity(StrUtils.uuid())
.setJobData(jobDataMap)
.build();
复制代码
//建立SimpleTrigger startTime end 分别表示触发器的首次触发时间和再也不被触发的时间
SimpleTrigger trigger = newTrigger()
.withIdentity("trigger", "group")
.startAt(startTime)
.endAt(end)
.withSchedule(
simpleSchedule().withIntervalInHours(
executeFrequency).withRepeatCount(
executeBatch)).build();
复制代码
CronTrigger 能够配置更复杂的触发时刻表,基于日历的做业触发器。使用SimpleTrigger触发器须要设置不一样的属性支撑,代码编写比较多,而且不灵活。而CornTrigger就比较灵活,能够经过设计Corn表达式来控制复杂的触发时间表。算法
Corn表达式:用于配置CornTrigger实例,由7个表达式组成的字符串,描述了时间表的详细信息。bash
//建立CornTrigger 好比下面的就是设计天天中午十二点整触发
CronTrigger trigger = newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule("0 0 12 * * ?")).build();
// 把job和trigger加入调度
scheduler.scheduleJob(jobDetail, trigger);
//启动scheduler
scheduler.start();
复制代码
对于Corn的理解参考:
mp.weixin.qq.com/s/-0kwxC2lz…?
// 把job和trigger加入调度
scheduler.scheduleJob(jobDetail, trigger);
//启动scheduler
scheduler.start();
复制代码
//一个完整的实例
private void quartzOrderReturn(List<String> returnIds) {
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("returnIds", returnIds);
//1. 建立一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
JobDetail jobDetail = JobBuilder.newJob(QuartzOrderReturn.class)// 定义Job类为QuartzOrderReturn类,这是真正的执行逻辑所在
.withIdentity(StrUtils.uuid())
.setJobData(jobDataMap)
.build();
// 2. 定义一个Trigger,定义该job在10秒后执行,而且执行一次
Date startTime = new Date();
startTime.setTime(startTime.getTime() + 10000L);
SimpleTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(StrUtils.uuid(), HeaderNameConstants.getQuartzTrigger()).startNow()// 定义名字和组
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(2)//定义时间间隔是2秒
.withRepeatCount(0)//定义重复执行次数是无限次
)
.build();
// 4. 将trigger和jobdetail加入这个调度
scheduler.scheduleJob(jobDetail, trigger);
// 5. 启动scheduler
scheduler.start();
// 6. 任务执行后20秒后休眠
Thread.sleep(startTime.getTime() + 20000L);
// 7. 若是定时任务开启则关闭
if (scheduler.isStarted()) {
scheduler.shutdown(true);
}
} catch (SchedulerException | InterruptedException e) {
e.printStackTrace();
}
}
复制代码
//每一个2秒执行一次
string cronParam = "*/2 * * * * ?";
//建立计划任务抽象工厂
ISchedulerFactory sf = new StdSchedulerFactory();
//建立计划任务
IScheduler sched = sf.GetScheduler();
//建立job
JobDetail job = new JobDetail("myJob","group", typeof(MyJob));
//建立触发器
Trigger trigger = new CronTrigger("myTrigger","group",cronParam);
//将job和trigger注入到计划任务中
sched.ScheduleJob(job, trigger);
//启动计划任务
sched.Start();
//关闭计划任务
//sched.Shutdown();
复制代码
参考:
www.cnblogs.com/wangjiming/…
定时通常是使用时间轮(time wheel)算法实现。 时间轮算法简单来讲能够用下图表示,其主体是一个循环列表,框架
新任务加入时,会根据目前指针所在位置和须要等待的时间,肯定保存在时钟的哪一个位置。时间轮有3个重要的属性参数,ticksPerWheel(一轮的tick数),tickDuration(一个tick的持续时间)以及 timeUnit(时间单位)。参考连接:www.zhihu.com/question/41… www.kafka.cc/archives/24…ide
1.抽象封装Job类函数
2.页面管理多个定时任务post