现在的位置: 首页 > 综合 > 正文

QuartZ一些概念和例子

2014年06月28日 ⁄ 综合 ⁄ 共 5375字 ⁄ 字号 评论关闭

1、Quartz 简介 
a、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。 
b、主页:http://www.quartz-scheduler.org/ 

c、目前最近版本:Quartz 1.8.0 Released - 04/22/2010 

2、笔记记录: 

JobExecutionContext

   当 Scheduler 调用一个 Job,一个 JobexecutionContext 传递给 execute() 方法。         
   JobExecutionContext 对象让 Job 能访问 Quartz 运行时候环境和 Job 本身的明细数据。

Scheduler生命周期中的方法 
  scheduler.start();   开始
  scheduler.shutdonw(); 结束
  注意:别在 shutdown() 之后调用 start() 
  Scheduler 实例被关闭之后你就不能调用它的 start() 方法了。这是因为 shutdown() 方法销毁了为   
  Scheduler 创建的所有的资源(线程,数据库连接等)。假如你在 shutdown() 之后调用 start()你将
  收到 SchedulerException 的异常。

org.quartz.Job 接口

  把 Quartz 作用到 Java 类上唯一要做的就是让它实现 org.quartz.Job 接口。你的 Job 类可以实现
  任何其他想要的接口或继承任何需要的基类,但是它自己或是它的超类必须实现这个 Job 接口。这个
  Job 接口只定义了单个方法:

   public void execute(JobExecutionContext context)   
     throws JobExecutionException; 

JobDetail

  对于部署在 Scheduler 上的每一个 Job 只创建了一个 JobDetail 实例。JobDetail 是作为 Job 实
  例进行定义的

JobDataMap

  org.quartz.JobDataMap 来定义 Job 的状态。JobDataMap 通过它的超类 org.quartz.util.DirtyFlagMap 
  实现了 java.util.Map 接口,你可以向 JobDataMap 中存入键/值对,那些数据对可在你的
  Job 类中传进行访问。这是一个向你的 Job 传送配置的信息便捷方法。
  // Every job has its own job detail   
  JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); 

以下是例子:

a、构建一个简单的
Quartz 程序 

My_Job.java

package org.hyz.quartz;

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;

public class My_Job implements Job{//一个普通的job,无状态的job

//	public class My_Job implements StatefulJob{	//有状态的job
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		// TODO Auto-generated method stub
//		Object o=context.getJobDetail().getJobDataMap().get("my1");
//		Object o1=context.getTrigger().getJobDataMap().get("my2");//触发器中的map
		
		Object o2=context.getMergedJobDataMap().get("my1");//两者合并,当名字一样时trigger覆盖jobdetail
		System.out.println(o2+"  "+new Date());
	}
}

上面是一个job类,只要实现了job接口就可以成为一个job任务,重写了 Job 接口中的 execute 方法,当调度程序开始运行后,系统会自动调用 HelloWorld 的 execute 方法,也就相当于 TimerTask类中的 run 方法。

a、无状态的Job:继承 org.quartz.Job,对于每一次Job的执行,都会创建一个新的实例JobDetail,Http协议也是无状态的,每次请求都是新的

有状态的Job:继承 org.quartz.StatefulJob,不是指Job有状态,而是指JobDetail任务描述的状态,所以Job还是新的

使用有状态的 Job(指的是JobDetail的状态)

  当你需要在两次 Job 执行间维护状态的话,Quartz 框架为此提供了 org.quartz.StatefulJob 接口。
  StatefulJob 接口仅仅是扩展了 Job 接口,未加入新的方法。你只需要通过使用与 Job 接口相同的 
  execute() 方法简单的实现 StatefulJob 接口即可。假如你有已存在的 Job 类,你所有要做的只是
  改变 Job 的接口为 org.quartz.StatefulJob。

改变有状态 Job 的 JobDataMap

  你可以在有状态 Job 中简单的通过 map 的 put() 方法来修改 JobDataMap.已存在的任何数据会被新
  的数据覆盖掉。你也能对无状态的 Job 这么做,但是因为对于无状态 Job 来说,JobDataMap 不会持
  久化,所以数据不会保存下来。对于 Trigger 和 JobExecutionContext 上的 JobDataMap 的数据修改
  也是没能保存下来的。

b、getMergedJobDataMap()合并,可以直接取Jdetail或Trigger中设置的map中的值

c、scher.start()方法可以在任何地方调用,你的触发器可以随时增加或删除

d、Quartz
支持同时运行多个 Job,他会根据 quartz.properties 初始化相应的线程 


MyQuart.java

package org.hyz.quartz;

import java.text.ParseException;
import java.util.Calendar;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.NthIncludedDayTrigger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class MyQuart {
	public void test1() {
		//创建一个任务描述JobDetail
		JobDetail jd = new JobDetail("my_job", Scheduler.DEFAULT_GROUP,My_Job.class);
		jd.getJobDataMap().put("my1", "ab");

		//创建触发器
//		Trigger str = TriggerUtils.makeSecondlyTrigger(1,5);
//		tr.setName(jd.getFullName()+"-Trigger");
		SimpleTrigger str=new SimpleTrigger();//没设置组名,是默认的
		str.setRepeatInterval(1000);
		str.setRepeatCount(5);//执行次数
		str.setName(jd.getFullName()+"-Trigger");//getFullName得到组名.my_job
		str.getJobDataMap().put("my2", "cd");//同样触发器也有map
		
		Calendar c = Calendar.getInstance();
		str.setStartTime(c.getTime());//开始时间,必须设置
		
		//获得调度器Scheduler接口
		Scheduler scher=null;
		try {
			scher=StdSchedulerFactory.getDefaultScheduler();
			
//			scher.start();//可以放在前面,同样执行
			
			scher.scheduleJob(jd,str);//把任务和触发器添加到Scheduler里面
			scher.start();//开始启动
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void test2() {
		JobDetail jd = new JobDetail("my_job1", Scheduler.DEFAULT_GROUP,My_Job.class);
		jd.getJobDataMap().put("my1", "ab");

		//处理年月日的Trigger
		NthIncludedDayTrigger ndt=new NthIncludedDayTrigger();
		ndt.setName(jd.getName()+"-Trigger");
		ndt.setIntervalType(NthIncludedDayTrigger.INTERVAL_TYPE_WEEKLY);//设置类型
		ndt.setN(Calendar.MONDAY);//每周一
		ndt.setFireAtTime("12:00:00");
		
		Calendar c = Calendar.getInstance();
		ndt.setStartTime(c.getTime());//开始时间,必须设置

		Scheduler scher=null;
		try {
			scher=StdSchedulerFactory.getDefaultScheduler();
			scher.scheduleJob(jd,ndt);
			scher.start();
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void test3() {
		JobDetail jd = new JobDetail("my_job3", Scheduler.DEFAULT_GROUP,My_Job.class);
		jd.getJobDataMap().put("my1", "ab");
		
		//cron触发器
		CronTrigger ctr=null;
		try {
			ctr = new CronTrigger(jd.getFullName()+"-Trigger", Scheduler.DEFAULT_GROUP, "* * * * * ? *");//注意周和日
		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Calendar c = Calendar.getInstance();
		ctr.setStartTime(c.getTime());
		
		Scheduler scher=null;
		try {
			scher=StdSchedulerFactory.getDefaultScheduler();
			scher.scheduleJob(jd,ctr);
			scher.start();//开始启动
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		MyQuart my=new MyQuart();
//		my.test1();
		my.test2();
		my.test3();
	}
}

以上是一些常用的触发器:SimpleTrigger,NthIncludedDayTrigger,CronTrigger;

Trigger不是与Job绑定,而是与JobDetail任务描述绑定.一般触发器没设置组名的话,也是默认的scheduler.DEFAULT_GROUP;

为一个 Job 使用多个 Trigger

  单个 JobDetail 能够支持多个 Trigger,但一个 Trigger 只能被指派给一个 Job。



抱歉!评论已关闭.