一、核心概念
 
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. hdu 4061 A Card Game

    思路: 分析:假设取的牌顺序是一个序列,那么这种序列在末尾为1时是和取牌序列一一对应的,且是符合“游戏结束时牌恰好被取完”的一种情况. 简证:1.在序列中,任一数 i 的后一个数 j 是必然要放在第 ...

  2. SQL Server 基础 之 GROUP BY子句

    GROUP BY 子句用于聚合信息 先看个实例,没有使用 GROUP BY 子句 SELECT SalesOrderID,OrderQty FROM Sales.SalesOrderDetail WH ...

  3. php截取字符串中的关键字,并高亮显示

    <?php $str = "hahaceshi测试一下关键字高亮显示,以及长字符串截取的问题!"; $key = "关键字"; $r = sub_key_ ...

  4. oracle基础知识和常见问题

    第一步新建数据库.名称:suning用户名:sys和system密码:lsw123456在cmd启动监听的命令  lsnrctl start如果无法启动 lsnrctl start原因可能是liste ...

  5. Linux问题定位工具大放送

    我们在程序定位问题时,经常不知所错,但是在linux有很多强大的工具,只要我们合理利用,一定见奇效. 主要会遇到以下问题: 1 mem高 2 cpu高 3 io高 4 网络延迟高 vargrind:h ...

  6. 绑定CPU

    处理器的亲和性 软亲和性(affinity) 意味着进程并不会在处理器之间频繁迁移,而 硬亲和性(affinity) 则意味着进程需要在您指定的处理器上运行. 通常 Linux 内核都可以很好地对进程 ...

  7. outlook圆角table

    <table cellpadding="0" cellspacing="0" border="0" width="800&q ...

  8. 将EXE作为资源,然后在释放到磁盘上并运行该exe程序(使用了FindResource,LoadResource,然后用CFile写成一个文件)

    // 将exe作为资源加入,然后再释放出来,并运行 try { HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_EXE1), _T(" ...

  9. Java:Object类

    objcet类中涉及的多态的扩展性,由于Object是所有类的根类,所以它可以接收任意类型的数据,包括基本数据类型.因为这一特点,它可以对多态性进行扩展. 1.创建一个Demo类来判断类类型 clas ...

  10. ie6 js报错unterminated string constant

    原因1:读取js文件时选用的编码不匹配导致该错误. 解决办法: 方法1:修改js的存储编码.可以使用note++打开js文件,再用UTF-8编 码方式保存并取代原来的js文件即可,并且在. <s ...