一、核心概念
 
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系列<一>模拟定时组件小程序的更多相关文章

  1. Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库

    Wuss Weapp 一款高质量,组件齐全,高自定义的微信小程序 UI 组件库 文档 https://phonycode.github.io/wuss-weapp 扫码体验 使用微信扫一扫体验小程序组 ...

  2. 微信小程序 MinUI 组件库系列之 price 价格组件

    MinUI 是基于微信小程序自定义组件特性开发而成的一套简洁.易用.高效的组件库,适用场景广,覆盖小程序原生框架.小程序组件化框架等,并且提供了高效的命令行工具.MinUI 组件库包含了很多基础的组件 ...

  3. 微信小程序开发系列教程三:微信小程序的调试方法

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...

  4. 定时组件quartz系列<三>quartz调度机制调研及源码分析

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  5. 定时组件quartz系列<二>quartz的原理

    Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便.   一.核心概念   Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可.   1. ...

  6. 定时组件quartz系列<二>quartz的集群原理

    1.基本信息:      Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2Se和J2EE应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它 来为执行一个作业而创建简单的或 ...

  7. xmlplus 组件设计系列之零 - xmlplus 简介

    xmlplus 是什么 xmlplus 是博主写的一个 JavaScript 框架,用于快速开发前后端项目. xmlplus 基于组件设计,组件是基本的构造块.评价组件设计好坏的一个重要标准是封装度. ...

  8. 两百条微信小程序跳坑指南(不定时更新)

    微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...

  9. 微信小程序~基础组件

    (1)视图容器 名称 功能说明 movable-view 可移动的视图容器,在页面中可以拖拽滑动 cover-image 覆盖在原生组件之上的图片视图 cover-view 覆盖在原生组件之上的文本视 ...

随机推荐

  1. Linux客户/服务器程序设计范式1——并发服务器(多进程)

    引言 本文会写一个并发服务器(concurrent server)程序,它为每个客户请求fork出一个子进程. 注意 1. 信号处理问题 对于相同信号,按信号的先后顺序依次处理.可能会产生的问题是,正 ...

  2. C Primer Plus之文件输入/输出

    文件 一个文件通常就是磁盘上的一段命名的存储区.但对于操作系统来说,文件就会更复杂一些.例如,一个大文件可以存储在一些分散的区段中,或者还会包含一些使操作系统可以确定其文件类型的附加数据. C将文件看 ...

  3. 23种设计模式学习一(单列模式)singleton

    单列模式的类(单线程下的) class Singleton { private static Singleton instance; private Singleton() { } public st ...

  4. linux系统中如何进入退出vim编辑器,方法及区别

    在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了.偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致强 ...

  5. 【查找结构4】红黑树 [RBT]

    红黑树的性质与定义 红黑树(red-black tree) 是一棵满足下述性质的二叉查找树: 1. 每一个结点要么是红色,要么是黑色. 2. 根结点是黑色的. 3. 所有叶子结点都是黑色的(实际上都是 ...

  6. SSIS ->> Error Handling

    Event Handler Each task and container raises events as it runs, such as an OnError event, among seve ...

  7. Hadoop、Pig、Hive、Storm、NOSQL 学习资源收集

    (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http://lib.open-open.com/view/1333428291655 http://blo ...

  8. OpenCV Manager package was not found

    http://www.tuicool.com/articles/322Yj2 !! [1]的底部就有解决办法,一般“\OpenCV-2.4.6-android-sdk\apk”这个路径下就是 Open ...

  9. HDOJ ——统计难题

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

  10. hdu - 1829 A Bug's Life (并查集)&&poj - 2492 A Bug's Life && poj 1703 Find them, Catch them

    http://acm.hdu.edu.cn/showproblem.php?pid=1829 http://poj.org/problem?id=2492 臭虫有两种性别,并且只有异性相吸,给定n条臭 ...