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

Quartz

2013年12月03日 ⁄ 综合 ⁄ 共 5621字 ⁄ 字号 评论关闭
文章目录

1.简单实例

SimpleJob.java

package com.test.job;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class SimpleJob implements Job{

    public void execute(JobExecutionContext context)

           throws JobExecutionException {

       // your business logic

       // ...

       System.out.println("simpleJob running ....");

    }

}

TestSimpleJob.java

package com.test.job;

import java.text.ParseException;

import org.quartz.CronExpression;

import org.quartz.CronTrigger;

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.SchedulerException;

import org.quartz.SimpleTrigger;

import org.quartz.impl.StdSchedulerFactory;

public class TestSimpleJob {

    public static void main(String[] args){

       try {

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

          

           String jobName = "simpleJob";

           String groupName = "DEFAULT";

          

           //删除作业

           if(scheduler.getJobDetail(jobName,groupName) != null){

              scheduler.deleteJob(jobName, groupName);

           }

          

           //作业的详细信息

           //任务名称,任务组名称,任务实现类

           JobDetail jobDetail = new JobDetail(jobName,groupName,SimpleJob.class);

          

           //创建简单触发器

           SimpleTrigger simpleTrigger = new SimpleTrigger("simpleTrigger",null);

           simpleTrigger.setRepeatCount(100); // 调用100次

           simpleTrigger.setRepeatInterval(5*1000);  //每5秒钟调用一次

           //注册作业

           scheduler.scheduleJob(jobDetail, simpleTrigger);

          

          

           CronTrigger cronTrigger = new CronTrigger("cronTrigger",null);

           CronExpression cronExpression = null;

           try {

              cronExpression = new CronExpression("0 0 12 * * ?");  //每天12点运行

              cronTrigger.setCronExpression(cronExpression);

             

              //注册作业

              scheduler.scheduleJob(jobDetail, cronTrigger);

             

              if(! scheduler.isShutdown()){

                  scheduler.start();

              }

             

          

           } catch (ParseException e) {

              e.printStackTrace();

           }

          

       } catch (SchedulerException e) {

           e.printStackTrace();

       }

    }

}

Quartz是一个开源的作业调度框架,完全由java写的,你能通过它创建简单或者复杂的任务。他能提供巨大的灵活性,但又不牺牲简单性。

Quartz的核心概念 :调度器、触发器、作业

调度器(Scheduler)

Scheduler负责管理Quartz的运行环境,Quartz它是基于多线程架构的,它启动的时候会初始化一套线程,这套线程会用来执行一些预置的作业。

要创建一个作业并能够被触发调用,必须在Scheduler上面注册一个JobDetail和Trigger。

Scheduler提携了所有Trigger和JobDetail,使它们协调工作。这些Trigger和JobDetail通过自身的name和group属性区分。

       Scheduler 由SchedulerFactory产生,我们可以通过以下方式获取Scheduler的实例:

     //从ServletContext上下文中查找SchedulerFactory

     SchedulerFactory   factory = (SchedulerFactory)

ServletActionContext.getServletContext().getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");

   //获取Scheduler对象

   Scheduler defScheduler = factory.getScheduler();

作业

Job

任务,其实就是一个接口。要创建一个任务,必须得实现这个接口。该接口只有一个execute方法,任务每次被调用的时候都会执行这个execute方法的逻辑。

public class TestJob impletemens org.quartz.Job{

         @Override

         public void execute(JobExecutionContext context) throws JobExecutionException{

                   // you business logic

                   // …

                 System.out.println("########### this is testJob running  ############");

     }

}

JobDetail

JobDetail 用来保存我们作业的详细信息。一个JobDetail可以有多个Trigger,但是一个Trigger只能对应一个JobDetail。下面是JobDetail的一些常用的属性和含义

参数名

类型

备注

name

String

任务的名称,必须

group

String

任务所在组,默认为DEFAULT

jobClass

Class

任务的实现类,必须

description

String

描述

jobDataMap

JobDataMap

用来给作业提供数据支持的数据结构

volatility

Boolean

重启应用之后是否删除任务的相关信息,默认false

durability

Boolean

任务完成之后是否依然保留到数据库,默认false

shouldRecover

Boolean

应用重启之后时候忽略过期任务,默认false

jobListeners

Set

监听器

JobDataMap

这是一个给作业提供数据支持的数据结构,使用方法和java.util.Map一样,非常方便。当一个作业被分配给调度器时,JobDataMap实例就随之生成。

Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用不同的执行方案。无状态任务在执行时拥有自己的JobDataMap拷贝,对JobDataMap的更改不会影响下次的执行。而有状态任务共享共享同一个JobDataMap实例,每次任务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。

正因为这个原因,无状态的Job可以并发执行,而有状态的StatefulJob不能并发执行,这意味着如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度,因此除非必要,应该尽量使用无状态的Job。

如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。

JobDataMap实例也可以与一个触发器相关联。这种情况下,对于同一作业的不同触发器,我们可以在JobDataMap中添加不同的数据,以便作业在不同时间执行时能够提供更为灵活的数据支持(学校上午放眼保健操录音第一版,下午放第二版)。

不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。

触发器(Trigger)

Trigger是一个抽象类,Quartz提供了两个比较常用的触发器SimpleTrigger和CronTrigger。它们都是Trigger的子类

SimpleTrigger

这是一个简单的触发器,通过它我们可以定义触发的时间,并选择性的设定重复的次数和间隔时间。它有以下常用的属性

参数名

参数类型

备注

name 

String

触发器名称

group 

String

触发器组名称

repeatCount 

int

重复次数,注意:如果为0表示不执行,-1表示不限制次数(直到过期),默认为0

repeatInterval 

long

间隔时间,注意:是以毫秒为单位

startTime 

Date

开始时间,默认当前时间

endTime 

Date

过期时间,默认一直执行(直到执行次数已达到repeatCount)

CronTrigger

这个触发器的功能非常强大,而且非常灵活,但需要掌握有关的Cron表达式知识

参数名

参数类型

备注

name 

String

触发器名称

group 

String

触发器组名称

cronEx 

CronExpression

规则表达式

startTime 

Date

开始时间,默认当前时间

endTime 

Date

过期时间,默认一直执行(直到执行次数已达到repeatCount)

触发器规则表达式配置:

格式:

[秒] [分] [小时] [日] [月] [周] [年]

格式说明:

位置

时间域名

是否必须

允许值

允许通配符

1

0-59

, - * /

2

0-59

, - * /

3

小时

0-23

, - * /

4

1-31

, - * ? / L W

5

1-12

, - * /

6

1-7或MON-SUN

, - * ? / L #

7

empty或1970-2099

, - * /

通配符说明:

*

可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”

?

该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符

-

表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发

,

表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发

/

x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y

L

该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五

W

该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围

#

该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发

转自javaeye xiaoyaoke08

抱歉!评论已关闭.