QuartZ一些概念和例子

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。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值