定时组件quartz系列<一>模拟定时组件小程序
一、核心概念
Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可。
1、Job
表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context)
2、JobDetail
JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。
3、Trigger代表一个调度参数的配置,什么时候去调。
4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。
二模拟案例
【1】定时任务类
package com.yeepay.sxf.testQuartz; import java.util.Map;
/**
* job类,这个类非常简单,只有一个execute方法,该方法是定时job具体执行的内容
* 也就是定时任务
* @author sxf
*
*/
public class Job {
public void exectute(Map<String, String> jobData){
System.out.println("******************");
System.out.println(jobData.get("type")+":Test Job Run at:"+System.currentTimeMillis());
System.out.println("******************");
}
}
【2】定时任务类的详细信息
package com.yeepay.sxf.testQuartz; import java.util.HashMap;
/**
* 定时的详细信息
* 定时的相信信息(1)这个定时信息对应的任务类
* (2)这个定时信息对应的任务类的参数,方法
* @author sxf
*
*/
public class JobDetail { private Class<? extends Job> clazz;
private String jobName;
private HashMap<String, String> jobData; //无参构造
public JobDetail(){
jobData =new HashMap<String, String>();
}
//有参构造
public JobDetail(String name,Class<? extends Job> clazz){
this();
this.jobName=name;
this.clazz=clazz;
} public int hashCode(){
final int prime=31;
int result=1;
result=prime*result+((jobName==null)?0:jobName.hashCode());
return result;
} /**
* 用来通过在list中使用key匹配获取jobdetail
*/
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj==null){
return false;
}
JobDetail other=(JobDetail) obj;
if(jobName==null){
if(other.jobName!=null){
return false;
}
}else if(!jobName.equals(other.jobName)){
return false;
}
return true;
}
public Class<? extends Job> getClazz() {
return clazz;
}
public void setClazz(Class<? extends Job> clazz) {
this.clazz = clazz;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public HashMap<String, String> getJobData() {
return jobData;
}
public void setJobData(HashMap<String, String> jobData) {
this.jobData = jobData;
} }
【3】定时的触发器
package com.yeepay.sxf.testQuartz;
/**
* Trigger类,记录下次运行作业的时间和运行job的key
* 一个触发器(1)内部维护一个定时任务的执行策略
* (2)内部同时维护一个定时的详细信息
* (3)触发器和定时详细信息是一对一的关系
* @author sxf
*
*/
public class Trigger implements Comparable { /**
* 定时的详细信息
*/
private String jobKey;
/**
* 定时的执行策略(下次执行时间)
*/
private long nextFireTime; /**
* 在TreeMap中可以根据下次运行时间排序
*/
@Override
public int compareTo(Object o) {
Trigger d=(Trigger) o;
return (int)(this.nextFireTime-d.getNextFireTime());
} /**
* 测试是只想运行一次,使用-1来退出
*/
public void resert(){
setNextFireTime(-1);
} public String getJobKey() {
return jobKey;
} public void setJobKey(String jobKey) {
this.jobKey = jobKey;
} public long getNextFireTime() {
return nextFireTime;
} public void setNextFireTime(long nextFireTime) {
this.nextFireTime = nextFireTime;
} }
【4】定时的初始化类(最关键的类)
package com.yeepay.sxf.testQuartz; import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TreeSet; /**
* Sucheduler类,最重要的类,用来启动和停止框架
* (1)内部维护触发器的集合
* (2)内部维护定时详细信息
* (3)内部维护一个线程类。该线程类是调度定时执行的关键
* @author sxf
*
*/
public class Scheduler { private List<JobDetail> jobList=new ArrayList<JobDetail>();
private TreeSet<Trigger> triggerList=new TreeSet<Trigger>();
private Object lockObject=new Object();
SchedulerThread thread; public void schedulerJob(JobDetail detail,Trigger trigger){
synchronized (lockObject) {
jobList.add(detail);
trigger.setJobKey(detail.getJobName());
triggerList.add(trigger); }
} public void start(){
this.thread=new SchedulerThread(lockObject, triggerList, jobList);
System.out.println("########## run scheduler at:"+new Date()+"##########");
thread.start();
} public void halt(){
thread.halt();
}
}
【5】定时任务调度的线程类
package com.yeepay.sxf.testQuartz; import java.util.List;
import java.util.TreeSet; /**
* 任务调度线程
* (1)从触发器集合中获取触发器
* (2)根据获取的触发器,确认执行策略,和定时的详细信息
* (3)如果符合当前执行策略,则触发器和定时详细信息配合执行定时任务
* @author sxf
*
*/
public class SchedulerThread extends Thread{ private Object lockObject;
private boolean shutDown=false;
private TreeSet<Trigger> triggerList;
private List<JobDetail> jobList; public SchedulerThread(Object lockObject,TreeSet<Trigger> triggerList,List<JobDetail> joblist){
this.lockObject=lockObject;
this.triggerList=triggerList;
this.jobList=joblist;
} @Override
public void run() { while(!shutDown){
synchronized (lockObject) {
try {
//获取最近的触发器
final Trigger trigger=triggerList.pollFirst();//获取最近执行的作业
if(trigger==null){
lockObject.wait(100);
continue;
}
long curr=System.currentTimeMillis();
//从触发器中获取该触发器对应的执行策略
long nextTime=trigger.getNextFireTime();
while(nextTime>curr&&!shutDown){
curr=System.currentTimeMillis();
if(nextTime>curr+1){
lockObject.wait(nextTime-curr);
}
if(!shutDown){
//获取最早的定时任务在集合中的索引
int index=jobList.indexOf(new JobDetail(trigger.getJobKey(), null));
//获取最早的定时
JobDetail jobDetail=jobList.get(index);
//利用反射机制,获取定时任务的类
Job job=jobDetail.getClazz().newInstance();
//执行定时任务
job.exectute(jobDetail.getJobData());
trigger.resert();
nextTime=trigger.getNextFireTime();
if(nextTime!=-1){
triggerList.add(trigger);
}else{
break;
} }
}
} catch (Exception e) {
e.printStackTrace();
}finally{ }
}
}
} public void halt(){
synchronized (lockObject) {
shutDown=true;
lockObject.notifyAll();
}
} }
【6】客户端测试类
package com.yeepay.sxf.testQuartz; /**
* 客户端测试
* 该定时模拟,和jdk自带的TimerTask很相似。
* @author sxf
*
*/
public class ClientTest { public static void main(String[] args) {
final JobDetail detail1=new JobDetail("job1",Job.class);
detail1.getJobData().put("type", "job1");
final JobDetail detail2=new JobDetail("job2",Job.class);
detail2.getJobData().put("type", "job2");
final Trigger trigger1=new Trigger();
trigger1.setNextFireTime(System.currentTimeMillis()+30001);
final Trigger trigger2=new Trigger();
trigger2.setNextFireTime(System.currentTimeMillis()+10001); Scheduler scheduler=new Scheduler();
scheduler.schedulerJob(detail1, trigger1);
scheduler.schedulerJob(detail2, trigger2); scheduler.start();
try {
Thread.sleep(100001);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
scheduler.halt();
}
}
定时组件quartz系列<一>模拟定时组件小程序的更多相关文章
- Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库
Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...
- 微信小程序 MinUI 组件库系列之 price 价格组件
MinUI 是基于微信小程序自定义组件特性开发而成的一套简洁.易用.高效的组件库,适用场景广,覆盖小程序原生框架.小程序组件化框架等,并且提供了高效的命令行工具.MinUI 组件库包含了很多基础的组件 ...
- 微信小程序开发系列教程三:微信小程序的调试方法
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...
- 定时组件quartz系列<三>quartz调度机制调研及源码分析
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- 定时组件quartz系列<二>quartz的原理
Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便. 一.核心概念 Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可. 1. ...
- 定时组件quartz系列<二>quartz的集群原理
1.基本信息: Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2Se和J2EE应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它 来为执行一个作业而创建简单的或 ...
- xmlplus 组件设计系列之零 - xmlplus 简介
xmlplus 是什么 xmlplus 是博主写的一个 JavaScript 框架,用于快速开发前后端项目. xmlplus 基于组件设计,组件是基本的构造块.评价组件设计好坏的一个重要标准是封装度. ...
- 两百条微信小程序跳坑指南(不定时更新)
微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...
- 微信小程序~基础组件
(1)视图容器 名称 功能说明 movable-view 可移动的视图容器,在页面中可以拖拽滑动 cover-image 覆盖在原生组件之上的图片视图 cover-view 覆盖在原生组件之上的文本视 ...
随机推荐
- Jmeter 快速入门教程(三-3) -- 使用参数化
参数化:简单的来理解一下,我们录制了一个脚本,这个脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统. 这个时候就需要对用户名和密码进 ...
- linux下关于gz和bz2压缩格式的常用操作技巧
.gz和.bz2都是linux下压缩文件的格式,有点类似windows下的.zip和.rar文件..bz2和.gz的区别在于,前者比后者压缩率更高,后者比前者花费更少的时间. 也就是说同一个文件,压缩 ...
- hdu 4764 Stone (巴什博弈,披着狼皮的羊,小样,以为换了身皮就不认识啦)
今天(2013/9/28)长春站,最后一场网络赛! 3~5分钟后有队伍率先发现伪装了的签到题(博弈) 思路: 与取石头的巴什博弈对比 题目要求第一个人取数字在[1,k]间的某数x,后手取x加[1,k] ...
- 也谈SWD接口协议分析
这几日看到坛里有几个关于SWD协议相关的文章,自己也尝试了下,有点体会,也有些疑惑,写出来与大家分享和交流下. 以下我的模拟SWD接口的板子简称为Host,目标MCU(即我要连接的板子)简称为T ...
- php ++a和a++
<?php$a=$b=5;$a+$b=$a++-++$b;echo $b;?> 输出-1
- QT 读取文件夹下所有文件(超级简单的方法,不需要QDirIterator)
之前,用标准C++写过读取文件夹.现在用QT重写代码,顺便看了下QT如何实现,还是相当简单的.主要用到QDir,详细文档可见这里 A program that lists all the files ...
- Struts2笔记——Action校验器
在struts2中,我们可以实现对action的所有方法进行校验或者对action的指定方法进行校验. 对于输入校验struts2提供了两种实现方法: 1.采用手工编写代码实现. 2.基于XML配置 ...
- JBoss7配置指南
JBoss7配置指南 1. jboss各主要版本特性... 3 1.1. jboss4特性... 3 1.2. jboss5特性... 5 1.3. jboss6特性 ...
- chrome开发配置(四)生成项目及配置库引用
1.运行gclient runhooks --force .会重新下载个python 2.7版本的,并且下载好几个文件,大概1个多小时:
- hibernate配置之<property name="hbm2ddl.auto">create</property>导致每次创建SessionFactory都清空数据库中的数据
参考:http://stackoverflow.com/questions/6611437/how-to-make-hibernate-not-drop-tables 我遇到的问题就是: List l ...