`
booby325
  • 浏览: 386524 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Quartz基础

阅读更多

Quartz是一个完全由java编写的开源作业调度框架。适用于周期性Work需要


1. 启动Quartz


SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();

sched.start();
JobDetail jobDetail = new JobDetail("myJob", null, DumbJob.class);

Trigger trigger = TriggerUtils.makeHourlyTrigger(); // fire every hour
trigger.setStartTime(TriggerUtils.getEvenHourDate(new Date())); // start on the next even hour
trigger.setName("myTrigger");

sched.scheduleJob(jobDetail, trigger);


一旦一个scheduler被实例化,它就可以被启动(start),并且处于驻留模式,直到被关闭(shutdown)。注意,一旦scheduler被关闭(shutdown),则它不能再重新启动,除非重新实例化它。


2. Jobs And Triggers


Job接口是调度任务的父类,所有需要执行的代码都在Job的实现中。


package org.quartz;
public interface Job {

    public void execute(JobExecutionContext context)
      throws JobExecutionException;
}


当Job触发器触发时(在某个时刻),Execute (..)就被scheduler所调用。JobExecutionContext对象被传递给这个方法,它为Job实例提供了它的“运行时”环境-一个指向执行这个IJob实例的Scheduler句柄,一个指向触发该次执行的触发器的句柄,IJob的JobDetail对象以及一些其他的条目。


JobDetail对象由Quartz客户端在Job被加入到scheduler时创建。它包含了Job的各种设置属性以及一个JobDataMap对象,这个对象被用来存储给定Job类实例的状态信息。


Trigger对象被用来触发jobs的执行。你希望将任务纳入到进度,要实例化一个Trigger并且“调整”它的属性以满足你想要的进度安排。Triggers也有一个JobDataMap与之关联,这非常有利于向触发器所触发的Job传递参数。

Quartz打包了很多不同类型的Trigger,但最常用的Trigge类是SimpleTrigger和CronTrigger。SimpleTrigger用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。CronTrigger按照日历触发,例如“每个周五”,每个月10日中午或者10:15分。 


为什么要分为Jobs和Triggers?很多任务日程管理器没有将Jobs和Triggers进行区分。一些产品中只是将“job”简单地定义为一个带有一些小任务标识的执行时间。其他产品则更像Quartz中job和trigger的联合。而开发Quartz的时候,我们决定对日程和按照日程执行的工作进行分离。(从我们的观点来看)这有很多好处。 例如:jobs可以被创建并且存储在job scheduler中,而不依赖于trigger,而且,很多triggers可以关联一个job.另外的好处就是这种“松耦合”能使与日程中的Job相关的trigger过期后重新配置这些Job,这样以后就能够重新将这些Job纳入日程而不必重新定义它们。这样就可以更改或者替换trigger而不必重新定义与之相连的job标识符。


当向Quartz scheduler中注册Jobs 和Triggers时,它们要给出标识它们的名字。Jobs 和Triggers也可以被放“组”中。“组”对于后续维护过程中,分类管理Jobs和Triggers非常有用。Jobs和Triggers的名字在组中必须唯一,换句话说,Jobs和Triggers真实名字是它的名字+组。如果使Job或者Trigger的组为‘null’,这等价于将其放入缺省的Scheduler.DEFAULT_GROUP组中。


3. 关于Jobs和JobDetails

在所实现的类成为真正的“Job”时,期望任务所具有的各种属性需要通知给Quartz,通过JobDetail类可以完成这个工作.

 

JobDetail jobDetail = new JobDetail("myJob",         // job name
                                      sched.DEFAULT_GROUP,   // job group (you can also specify 'null' to use the default group)
                                      DumbJob.class);        // the java class to execute

Trigger trigger = TriggerUtils.makeDailyTrigger(8, 30);
trigger.setStartTime(new Date());
trigger.setName("myTrigger");

sched.scheduleJob(jobDetail, trigger);

public class DumbJob implements Job {
    public DumbJob() {
    }

    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {
      System.err.println("DumbJob is executing.");
    }
}

 

注意我们传递给scheduler一个JobDetail实例,JobDetail关联一个job,提供job的class,每次scheduler执行job时,在执行execute(...) 这前会创建一个实例.job必须有一个无参构造方法.


你可能想问如何提供配置 job实例.或者保存job状态在执行过程中.答案是JobDataMap.它是JobDetail的一部分.

JobDataMap 

JobDataMap被用来保存一系列的(序列化的)对象,这些对象在Job执行时可以得到。

JobDataMap是Map接口的一个实现,而且还增加了一些存储和读取主类型数据的便捷方法。

jobDetail.getJobDataMap().put("jobSays", "Hello World!");

jobDetail.getJobDataMap().put("myFloatValue", 3.141f);

jobDetail.getJobDataMap().put("myStateData", new ArrayList());


下面的代码展示了在Job执行过程中从JobDataMap 获取数据的代码

 

public class DumbJob implements Job {
    public DumbJob() {
    }

    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {
      String instName = context.getJobDetail().getName();
      String instGroup = context.getJobDetail().getGroup();

      JobDataMap dataMap = context.getJobDetail().getJobDataMap();

      String jobSays = dataMap.getString("jobSays");
      float myFloatValue = dataMap.getFloat("myFloatValue");
      ArrayList state = (ArrayList)dataMap.get("myStateData");
      state.add(new Date());

      System.err.println("Instance " + instName + " of DumbJob says: " + jobSays);
    }
}

 


Triggers也可以有JobDataMaps与之相关联。当scheduler中的Job被多个有规律或者重复触发的Triggers所使用时非常有用。对于每次独立的触发,你可为Job提供不同的输入数据。 从Job执行时的JobExecutionContext中取得JobDataMap是惯用手段,它融合了从JobDetail和从Trigger中获的JobDataMap,当有相同名字的键时,它用后者的值覆盖前者值。


StatefulJob——有状态任务 

现在,一些关于Job状态数据的附加论题:一个Job实例可以被定义为“有状态的”或者“无状态的”。“无状态的”任务只拥有它们被加入到scheduler时所存储的JobDataMap。这意味着,在执行任务过程中任何对Job Data Map所作的更改都将丢失而且任务下次执行时也无法看到。你可能会猜想出,有状态的任务恰好相反,它在任务的每次执行之后重新存储JobDataMap。有状态任务的一个副作用就是它不能并发执行。换句话说,如果任务有状态,那么当触发器在这个任务已经在执行的时候试图触发它,这个触发器就会被阻塞(等待),直到前面的执行完成。想使任务有状态,它就要实现StatefulJob 接口而不是实现Job接口.


jobs的其它属性 

这里简短地总结一下通过JobDetail对象可以定义Job的其它属性。 

Durability(持久性)-如果一个Job是不持久的, 一旦没有触发器与之关联,它就会被从scheduler 中自动删除。 

Volatility(无常性)-如果一个Job是无常的,在重新启动Quartz i scheduler 时它不能被保持。 

RequestsRecovery(请求恢复能力) -如果一个Job具备“请求恢复”能力,当它在执行时遇到scheduler “硬性的关闭”

       (例如:执行的过程崩溃,或者计算机被关机),那么当scheduler重新启动时,这个任务会被重新执行。

        这种情况下,JobExecutionContext.isRecovering() 属性将是true。 

JobListeners(任务监听器) -一个Job如果有0个或者多个JobListeners监听器与之相关联,当这个Job执行时,监听器被会被通知。


4. 关于Triggers更多内容


Priority

有时,当有多个Triggers时,Quartz没有足够的资源来同时立即处理scheduled的trigger.所以你可能要控制哪个先执行.在这种情况下,你要设置Trigger的priority,如果N个triggers不会同时触发.但此时只有有限的几个线程可


用.这时会先处理级别高的trigger.如果你没有设置级别,默认为5,下面为一个例子:

Calendar cal = Calendar.getInstance();

cal.add(Calendar.MINUTE, 5);

Trigger trig1 = new SimpleTrigger("T1", "MyGroup", cal.getTime());
Trigger trig2 = new SimpleTrigger("T2", "MyGroup", cal.getTime());
Trigger trig3 = new SimpleTrigger("T3", "MyGroup", cal.getTime());

JobDetail jobDetail = new JobDetail("MyJob", "MyGroup", NoOpJob.class);

// Trigger1 does not have its priority set, so it defaults to 5
sched.scheduleJob(jobDetail, trig1);

// Trigger2 has its priority set to 10
trig2.setJobName(jobDetail.getName());
trig2.setPriority(10);
sched.scheduleJob(trig2);

// Trigger2 has its priority set to 1
trig3.setJobName(jobDetail.getName());
trig2.setPriority(1);
sched.scheduleJob(trig3);

// Five minutes from now, when the scheduler invokes these three triggers
// they will be allocated worker threads in decreasing order of their
// priority: Trigger2(10), Trigger1(5), Trigger3(1)

 

Misfire Instructions——未触发指令 

Trigger的另一个重要属性就是它的“misfire instruction(未触发指令)”。如果因为scheduler被关闭而导致持久的触发器“错过”了触发时间,这时,未触发就发生了。不同类型的触发器有不同的未触发指令。缺省情况下,他们会使用一个“智能策略”指令——根据触发器类型和配置的不同产生不同动作。当scheduler开始时,它查找所有未触发的持久triggers,然后按照每个触发器所配置的未触发指令来更新它们。

开始工程中使用Quartz的时,应熟悉定义在各个类型触发器上的未触发指令。关于未触发指令信息的详细说明将在每种特定的类型触发器的指南课程中给出。可以通过MisfireInstruction属性来为给定的触发器实例配置未触发指令。


TriggerUtils - Triggers Made Easy(TriggerUtils——使Triggers变得容易) 

TriggerUtils类包含了创建触发器以及日期的便捷方法。使用这个类可以轻松地使触发器在每分钟,小时,日,星期,月等触发。使用这个类也可以产生距离触发最近的妙、分或者小时,这对设定触发开始时间非常有用。


TriggerListeners 实现TriggerListener接口的对象将可以收到触发器被触发的通知。


5. SimpleTrigger


SimpleTrigger让任务只在某个时刻执行一次,或者,在某个时刻开始,然后按照某个时间间隔重复执行,在某个时刻结束。SimpleTrigger包括这些属性:开始时间,结束时间,重复次数,重复间隔。所有这属性都是你期望它所应具备的,只有end-time属性有一些条目与之关联。


SimpleTrigger有几个不同的构造函数,下面我们来看看这结果构造函数:

 

public SimpleTrigger(String name, String group,Date startTime,Date endTime,int repeatCount,long repeatInterval)

SimpleTrigger Example 1 - Create a trigger that fires exactly once, ten seconds from now
long startTime = System.currentTimeMillis() + 10000L;
SimpleTrigger trigger = new SimpleTrigger("myTrigger", null,new Date(startTime),null,0,0L);

SimpleTrigger Example 2 - Create a trigger that fires immediately, then repeats every 60 seconds, forever
SimpleTrigger trigger = new SimpleTrigger("myTrigger", null, new Date(),null,SimpleTrigger.REPEAT_INDEFINITELY,60L * 1000L);

SimpleTrigger Example 3 - Create a trigger that fires immediately, then repeats every 10 seconds until 40 seconds from now
long endTime = System.currentTimeMillis() + 40000L;
SimpleTrigger trigger = new SimpleTrigger("myTrigger","myGroup", new Date(),new Date(endTime), SimpleTrigger.REPEAT_INDEFINITELY,10L * 1000L);

SimpleTrigger Example 4 - Create a trigger that fires on March 17 of the year 2002 at precisely 10:30 am, and repeats 5 times (for a total of 6 firings) - with a 30 second delay between each firing
java.util.Calendar cal = new java.util.GregorianCalendar(2002, cal.MARCH, 17);
cal.set(cal.HOUR, 10);
cal.set(cal.MINUTE, 30);
cal.set(cal.SECOND, 0);
cal.set(cal.MILLISECOND, 0);

Data startTime = cal.getTime()

SimpleTrigger trigger = new SimpleTrigger("myTrigger", null, startTime,null,5,30L * 1000L);

 

6. 一个可行的Quartz。
在ContextListener的init中,加载所有的Job的配置,并根据这些配置调用相应的Job。同时可以采用StatefulJob保存Job的状态{或者存储到数据库中}。
建立一个action与页面,在页面中可以查看当前所有Job的状态,并采用不同的方式去restart或者destory一个Job。

 

分享到:
评论

相关推荐

    QUARTZ项目实练

    1. **QUARTZ基础** - **Job接口**:在QUARTZ中,所有的任务都实现了`org.quartz.Job`接口,该接口定义了`execute(JobExecutionContext context)`方法,这是任务执行的入口点。 - **Trigger**:触发器决定了任务...

    Quartz任务监控管理

    1. **Quartz基础知识**:Quartz的核心概念包括Job(作业)、Trigger(触发器)和Scheduler(调度器)。Job是待执行的任务,Trigger定义了任务何时被执行,而Scheduler则负责管理和执行这些Job和Trigger。理解这些...

    spring quartz 表达式在线生成器

    1. **Quartz基础**:解释Quartz的基本概念,如Job、Trigger、Scheduler等,以及它们之间的关系。 2. **Spring与Quartz集成**:介绍如何在Spring应用中配置Quartz,包括使用`@EnableScheduling`注解开启调度,以及...

    springboot+mybatis+shiro+generator+quartz(基础框架)

    综上所述,这个基础框架集合了Spring Boot的便利性、MyBatis的灵活性、Shiro的安全管理、代码生成器的自动化、Quartz的定时任务调度以及Thymeleaf的模板渲染,为开发人员提供了一个全方位的工具链,使得企业级应用的...

    quartz封装

    1. **Quartz基础**: - Quartz的核心概念包括:Job(任务)、Trigger(触发器)、Scheduler(调度器)和Calendar(日历)。Job是待执行的任务,Trigger决定何时执行Job,Scheduler负责管理和执行Trigger和Job。 2....

    Quartz入门学习(真丶入门)

    一、Quartz基础 1. **作业(Jobs)与触发器(Triggers)**:在Quartz中,任务被称为作业(Job),而何时执行这些任务则由触发器(Trigger)决定。作业是实现业务逻辑的类,而触发器定义了执行作业的时间规则,如...

    Java定时Quartz测试案例

    Quartz是一款开源的作业调度框架,它为Java应用程序提供了丰富的定时任务管理能力。...这个案例提供了学习Quartz基础知识的一个起点,开发者可以在此基础上扩展出更复杂和实用的定时任务管理功能。

    quartz-1.7.3

    1. **Quartz基础**: - **设计理念**:Quartz的核心思想是提供一个可扩展、易用、可靠的平台来计划和执行工作项(Jobs)。这些工作项可以是任何Java对象,通过实现`org.quartz.Job`接口来定义。 - **触发器...

    一个简单的quartz定时器的demo

    总的来说,这个demo提供了Quartz基础用法的一个快速入门,帮助开发者理解如何在实际项目中利用Quartz实现定时任务。通过深入学习和实践,你可以掌握更复杂的调度策略,如并发控制、任务依赖关系以及异常处理等,从而...

    quartz定时任务

    1. **Quartz基础概念** - **Job**:Quartz中的任务单元,代表要执行的具体业务逻辑。 - **Trigger**:触发器,用于定义任务的执行时间,如cron表达式或间隔时间。 - **Scheduler**:调度器,负责管理和执行Job与...

    配置quartz相关

    Quartz基础 Quartz的核心概念包括`Job`(工作)、`Trigger`(触发器)和`Scheduler`(调度器)。`Job`代表要执行的任务,`Trigger`定义了任务何时被执行,而`Scheduler`负责管理和执行这些任务。 ### 2. Spring...

    springquartz源码

    1. **Quartz基础** - **基本概念**:Quartz主要由Job、Trigger和Scheduler组成。Job是执行的任务,Trigger是触发Job执行的时间规则,Scheduler负责安排和管理Job与Trigger。 - **Job和Trigger**:Job接口定义了...

    schedule-job, 基于Spring Boot Quartz 的分布式任务调度系统.zip

    【Quartz基础知识】 Quartz是Java平台上的一款开源作业调度框架,用于创建和管理定时任务。它提供了强大的调度能力,支持Cron表达式、简单触发器、复合触发器以及任务集群等。Quartz可以被集成到任何Java应用中,...

    Spring Quatz 书-Quartz.Job.Scheduling.Framework.Building

    1. **Quartz基础**:首先,书中会介绍Quartz的基本概念,包括Job、Trigger、Scheduler等核心组件,以及它们之间的关系和工作原理。读者可以了解到如何定义作业,如何设置触发器,以及如何通过Scheduler安排作业的...

    quartz的小demo

    1. **Quartz基础** - **核心概念**:Quartz的核心组件包括Job(任务)、Trigger(触发器)和Scheduler(调度器)。Job定义了要执行的任务,Trigger决定何时触发Job,而Scheduler负责管理和执行这些任务。 - **Job...

    quartz-demo.zip

    1. **Quartz基础**: - **Job接口**:Quartz的核心接口,定义了一个执行任务的类需要实现的方法。 - **Trigger**:负责触发Job的执行,可以设置定时规则,如简单触发器、cron触发器等。 - **Scheduler**:调度器...

    定时器quartz的应用

    一、Quartz基础 1. **任务与触发器**: - **Job**:在Quartz中,任务被称为Job,它是执行具体工作的一段代码。通过实现`org.quartz.Job`接口或者继承`org.quartz.StatefulJob`(状态感知任务)类来创建自定义Job。...

    java quartz计划任务中间件使用教程,每天定时备份数据库的插件jspweb java网站工程.rar

    1. **Quartz基础知识** - **核心概念**:Quartz主要由Job(任务)、Trigger(触发器)和Scheduler(调度器)三部分组成。Job定义了要执行的任务,Trigger定义了任务的执行时间,Scheduler负责管理和协调Job和...

    quartz-2.2.1使用demo

    1. **Quartz基础** - **Job接口**:这是所有任务类需要实现的接口,其中包含一个`execute`方法,这是实际执行任务的地方。 - **Trigger**:触发器定义了任务何时开始以及执行频率。有多种类型的触发器,如...

    QuartzSpring

    1. **Quartz基础**:首先,我们需要理解Quartz的核心概念,包括Job(任务)、Trigger(触发器)和Calendar(日历)。Job是需要执行的任务,Trigger定义了何时触发Job,而Calendar用于定义触发规则的例外情况。 2. *...

Global site tag (gtag.js) - Google Analytics