`

quartz 学习笔记

阅读更多

StdScheduler 通过文件加载的方式初始化Schedule工厂
 
  // Create an instance of the factory  
  StdSchedulerFactory factory = new StdSchedulerFactory();  
 
  // Create the properties to configure the factory  
  Properties props = new Properties();  
 
  // required to supply threadpool class and num of threads  
 
  props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,  
                    "org.quartz.simpl.SimpleThreadPool");  
 
  props.put("org.quartz.threadPool.threadCount", "10");  
   
  // Initialize the factory with properties  
  factory.initialize(props);
 
  Scheduler scheduler = factory.getScheduler();  
 
DirectSchedulerFactory通过硬编码的方式初始化Scheduler工厂

  DirectSchedulerFactory factory=DirectSchedulerFactory.getInstance();  
 
  // Initialize the Scheduler Factory with 10 threads  
  factory.createVolatileScheduler(10);  
 
  // Get a scheduler from the factory  
  Scheduler scheduler = factory.getScheduler();  
 
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; 

JobExecutionContext

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

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();  

使用有状态的 Job

  当你需要在两次 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 的数据修改
  也是没能保存下来的。

Job 的易失性

  一个易失性的 Job 是在程序关闭之后不会被持久化。一个 Job 是通过调用 JobDetail 的
  setVolatility(true) 被设置为易失性的。
 
  当你需要持久化 Job 时不应使用 RamJobStore,RamJobStore 使用的是非永久性存储器,
  所有关于 Job 和 Trigger 的信息会在程序关闭之后丢失。保存 Job 到 RamJobStore 有效的使得它们
  是易失性的。假如你需要让你的 Job 信息在程序重启之后仍能保留下来,你就该考虑另一种 JobStore
  类型,比如 JobStoreTX 或者 JobStoreCMT。

Job 持久性

  一个持久的 Job 是它应该保持在  JobStore 中的,甚至是在没有任何 Trigger 去触发它的时候。我们
  说,你设置了一个单次触发的 Trigger,触发之后它就变成了 STATE_COMPLETE 状态。Job 执行一次后
  就不再被触发了,这个 Trigger 部署之后只为了执行一次。这个 Trigger 指向的 Job 现在成了一个
  孤儿 Job,因为不再有任何 Trigger 与之相关联了。

  假如你设置一个 Job 为连续性的,即使它成了孤儿 Job 也不会从 JobStore 移除掉。这样可以保证在
  将来,无论何时你的程序决定为这个 Job 增加另一个 Trigger 都是可用的。假如调用了 JobDetail 的
  setDurability(false) 方法,那么在所有的触发器触发之后 Job 将从 JobStore 中移出。连续性的默
  认值是 false。因此,Job 和 Trigger 的默认行为是:当 Trigger 完成了所有的触发、Job 在没有
  Trigger 与之关联时它们就会从 JobStore 中移除。

Job 的可恢复性

  当一个 Job 还在执行中,Scheduler 经历了一次非预期的关闭,在 Scheduler 重启之后可恢复的 Job
  还会再次被执行。这个 Job 会再次重头开始执行。Scheduler 是没法知道在程序停止的时候 Job 执行
  到了哪个位置,因此必须重新开始再执行一遍。要设置 Job 为可恢复性,用下面的方法:
  public void setRequestsRecovery(boolean shuldRecover);
  默认时,这个值为 false,Scheduler 不会试着去恢复 job 的。

Scheduler 中移除 Job

  多种方式移除已部署的 Job。一种方式是移除所有与这个 Job 相关联的 Trigger;如果这个 Job 是非持久
  性的,它将会从 Scheduler 中移出。一个更简单直接的方式是使用 deleteJob() 方法:

  public boolean deleteJob(String jobName, String groupName)throws SchedulerException; 

中断 Job

  Quartz 包括一个接口叫做 org.quartz.InterruptableJob,它扩展了普通的 Job 接口并提供了一个
  interrupt() 方法:

  public void interrupt() throws UnableToInterruptJobException;

  可以提供 Job 部署时所用的 Job 的名称和组名调用 Scheduler 的 interrupte() 方法:

  public boolean interrupt(SchedulingContext ctxt, String jobName, String groupName) throws 
  UnableToInterruptJobException; 

框架所提供的 Job

  org.quartz.jobs.FileScanJob 检查某个指定文件是否变化,并在文件被改变时通知到相应监听器的 Job
  org.quartz.jobs.FileScanListener 在文件被修改后通知 FileScanJob 的监听器 
  org.quartz.jobs.NativeJob 用来执行本地程序(如 windows 下 .exe 文件) 的 Job
  org.quartz.jobs.NoOpJob 什么也不做,但用来测试监听器不是很有用的。一些用户甚至仅仅用它来导致
  一个监听器的运行
  org.quartz.jobs.ee.mail.SendMailJob 使用 JavaMail API 发送 e-mail 的 Job
  org.quartz.jobs.ee.jmx.JMXInvokerJob 调用 JMX bean 上的方法的 Job
  org.quartz.jobs.ee.ejb.EJBInvokerJob 用来调用 EJB 上方法的 Job

主处理线程:QuartzSchedulerThread

  Quartz 应用第一次运行时,main 线程会启动 Scheduler。QuartzScheduler 被创建并创建一个
  org.quartz.core.QuartzSchedulerThread 类的实例。QuartzSchedulerThread 包含有决定何时下一个
  Job 将被触发的处理循环。顾名思义,QuartzSchedulerThread 是一个 Java 线程。它作为一个非守护线
  程运行在正常优先级下。


QuartzSchedulerThread 的主处理循环的职责描述如下:

1. 当 Scheduler 正在运行时:

    A. 检查是否有转换为 standby 模式的请求。

       1. 假如 standby 方法被调用,等待继续的信号

    B. 询问 JobStore 下次要被触发的 Trigger.

       1. 如果没有 Trigger 待触发,等候一小段时间后再次检查

2. 假如有一个可用的 Trigger,等待触发它的确切时间的到来

    D. 时间到了,为 Trigger 获取到 triggerFiredBundle.

    E. 使用 Scheduler 和 triggerFiredBundle 为 Job 创建一个 JobRunShell 实例

    F. 告诉 ThreadPool 可能时运行 JobRunShell.

    这个逻辑存在于 QuartzSchedulerThread 的 run() 方法中。

QuartzSchedulerResources

  当工厂创建 Scheduler 实例时,它还会传递给 Scheduler 一个 org.quartz.core.QuartzSchedulerResoures
  实例。QuartzSchedulerResourecs 除包含以上东西之后,还有一个 ThreadPool 实例,它提供了一个工作者
  线程池来负责执行 Job。在 Quartz 中,ThreadPool 是由 org.quartz.spi.ThreadPool 接口 (因为 Quartz
  是在 JDK 1.5 之前产生的,所以需要自己的 ThreadPool 类确保向后的兼容性,Quartz   仍然用自己的
  ThreadPool 替代 Java 的) 表示的,并提供一个名为 org.quartz.simp.SimpleThreadPool 的具体实现类。
  SimpleThreadPool 有一个固定数目的工作者线程,在加载之后就不再减少或增多

Quartz 工作者线程

  Quartz 不会在 main 线程中处理你的 Job。如果这么做,会严重降低应用的可扩展性。相应的,Quartz
  把线程管理的职责委托给分散的组件。对于一般的 Quartz 设置 (这部分还是很费功夫的),都是用
  SimpleThreadPool  类处理线程的管理。SimpleThreadPool 创建了一定数量的 WorkerThread 实例来使得
  Job 能够在分散的线程中进行处理。WorkerThread 是定义在 SimpleThreadPool 类中的内部类,它实质上就是
  一个线程。要创建 WorkerThread 的数量以及为他们的优先级是配置在文件 quartz.properties 中并传入工厂的

JobRunShell 的 run() 方法

  虽然 WorkerThread 是真正的 Java 线程,JobRunShell 类也还是实现了 Runable。那意味着它可以作为一个
  线程并包含一个 run() 方法。在本章前面讨论过,JobRunShell 的目的是调用 Job 的 execute() 方法。
  不仅如此,它还要负责通知 Job 和 Trigger 监听器,在运行完成后还得更新此次执行的 Trigger 的信息。

org.quartz.SimpleTrigger

  正如其名所示,SimpleTrigger 对于设置和使用是最为简单的一种 Quartz Trigger。它是为那种需要在特定
  的日期/时间启动,且以一个可能的间隔时间重复执行 n  次的 Job 所设计的。

org.quartz.CronTrigger

  CronTrigger 允许设定非常复杂的触发时间表,顾名思义,CronTrigger 是基于 Unix 类似于 cron 的表达式。

org.quartz.NthIncludedDayTrigger
 
  它设计用于在每一间隔类型的第几天执行 Job。Quartz 的 Caldendar 也可与 Trigger 关联以此把周末与
  节假日考虑进来,并在必要时跳开这些日期。

为一个 Job 使用多个 Trigger

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

org.quartz.Calendar

  Quartz 定义了 org.quartz.Calendar 接口,所有的 Quartz Calendar 必须实现它。它包含了几个方法,
  但是有两个是最重要的:

  public long getNextIncludedTime(long timeStamp);  
  public boolean isTimeIncluded(long timeStamp);

作为一个 Quartz Job 的创建者和开发者,你可不必去熟悉 Calender 接口。这主要是因为已有的 Calendar
(Quartz 自带的) 需要应付的情况就不够多。开箱即用的,Quartz 包括许多的 Calender 实现足以满足你的要求

  org.quartz.impl.calendar.BaseCalender 为高级的 Calender 实现了基本的功能,实现了
  org.quartz.Calender 接口
  org.quartz.impl.calendar.WeeklyCalendar 排除星期中的一天或多天,例如,可用于排除周末
  org.quartz.impl.calendar.MonthlyCalendar 排除月份中的数天,例如,可用于排除每月的最后一天
  org.quartz.impl.calendar.AnnualCalendar  排除年中一天或多天
  org.quartz.impl.calendar.HolidayCalendar 特别的用于从 Trigger 中排除节假日

Calendar examle
 
 // Create an instance of the Quartz AnnualCalendar  
        AnnualCalendar cal = new AnnualCalendar();  
 
        // exclude July 4th  
        Calendar gCal = GregorianCalendar.getInstance();  
        gCal.set(Calendar.MONTH, Calendar.JULY);  
        gCal.set(Calendar.DATE, 4);  
 
        cal.setDayExcluded(gCal, true);  
 
        // Add to scheduler, replace existing, update triggers  
        scheduler.addCalendar("bankHolidays", cal, true, true);
       
  /* 
          * Set up a trigger to start firing now, repeat forever 
          * and have (60000 ms) between each firing. 
         */ 
        Trigger trigger = TriggerUtils.makeImmediateTrigger("myTrigger",  -1,60000);  

        trigger.setCalendarName("bankHolidays");  
       
        //HolidayCalender 类考虑的是年份。因此,如果你希望在后续三年中排除 7 月 4 日,
        //你需要把三年中的每个日期都作为要排除的项。而 AnnualCalender 可简单的为每年
        //设定要排除的日期

CronTrigger 使用起迄日期

  CronTrigger 的 setStartTime() 和 setEndTime() 方法来形成一个 "定时箱" 来触发。

JobStore 接口

  Quartz 为所有类型的 Job 存储提供了一个接口。这个接口位于 org.quartz.spi 包中,叫做
  JobStore。所有的 Job 存储机制,不管是在哪里或是如何存储他们的信息的,都必须实现这个接口。

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论
1 楼 tongkp 2013-11-26  
很不错,对我有很大的帮助,谢谢分享。

相关推荐

    Quartz学习笔记

    这个学习笔记将深入探讨Quartz的核心概念、主要功能以及如何在实际项目中使用它。 首先,我们要理解Quartz的基本架构。Quartz的核心组件包括Scheduler、Job、Trigger和Calendar。Scheduler是调度器,负责管理所有的...

    Quartz调度学习笔记

    Quartz 是一个强大的任务调度框架,由 OpenSymphony 开源组织开发,主要目的是提供一个用于在 Java 应用程序中安排任务执行的解决方案。Quartz 支持与 J2EE 和 J2SE 平台的无缝集成,允许开发者在各种类型的项目中...

    Spring.NET学习笔记25——整合Quartz.NET例子

    刘冬编写Spring.NET学习笔记25——整合Quartz.NET例子。 原文: http://www.cnblogs.com/GoodHelper/archive/2009/11/20/SpringNet_QuartzNet.html

    学习笔记_Quartz作业调度框架,使用corn表达式

    本学习笔记主要围绕Quartz的使用,特别是如何利用corn表达式来设置定时任务。 Quartz的核心概念包括Job(任务)、Trigger(触发器)和Scheduler(调度器)。Job是你要执行的实际业务逻辑,Trigger定义了Job何时被...

    Quartz入门学习(真丶入门)

    Quartz是一款开源的作业调度框架,它允许开发者创建和管理定时任务,以便在特定时间执行。在Java世界中,Quartz被广泛应用于...通过实践和学习,你将能够熟练掌握Quartz的使用,为你的项目带来更高效的自动化处理能力。

    quartz教程 quartz学习手册 quartz帮助手册

    六、Quartz学习资源 本教程、学习手册和帮助手册将详细阐述Quartz的各个方面,从基本使用到高级特性的实践,帮助开发者从初学者到精通者。通过阅读这些资料,你可以掌握如何在项目中有效地使用Quartz,提升系统的...

    Quartz1.8任务进程管理系统学习笔记一:版本1.8和之前版本的不同

    NULL 博文链接:https://jaykuen.iteye.com/blog/911106

    学习笔记 MHT2

    【学习笔记 MHT2】是一份综合性的IT学习资料,主要涵盖了JavaScript编程、软件开发工具、Web服务器技术、编码解码方法以及设计模式等多个领域的知识。以下是对这些知识点的详细阐述: 1. **JavaScript经典技巧**:...

    spring2.0学习笔记+spring定时任务

    标题中的“spring2.0学习笔记+spring定时任务”表明了这个压缩包文件包含的是关于Spring框架2.0版本的学习资料,特别是关于Spring的定时任务功能。Spring是Java开发中最广泛应用的轻量级框架之一,它提供了一整套...

    objective-c学习笔记

    学习笔记中可能包含了一些关于Objective-C图形编程的内容,如Core Graphics或Quartz 2D,它们是苹果平台进行低级绘图的API,可用于创建自定义视图和复杂的图形。 六、实践应用 理论学习后,通过编写简单的iOS应用...

    spring学习笔记

    这个“spring学习笔记”包含了与Spring框架相关的源代码和项目实践,旨在帮助学习者深入理解并掌握Spring的核心概念和技术。 首先,Spring的核心特性之一是依赖注入(Dependency Injection, DI),它允许开发者通过...

    SpringBoot学习笔记完整教程

    Spring Boot 是一个基于 Spring 框架的快速开发...这个完整的 Spring Boot 学习笔记涵盖了从基础到进阶的各个方面,通过学习和实践,你可以掌握 Spring Boot 开发的核心技能,从而高效地构建高质量的 Java 后端应用。

    若依RuoYi框架剖析笔记,该笔记是在学习江南一点雨所录课程再结合自己的理解所写

    《若依RuoYi框架剖析笔记》是基于江南一点雨的课程并结合个人理解整理而成,涵盖了项目改造、框架结构分析以及多个关键功能模块的深入探讨。以下将逐一解析这些知识点。 1、**项目改造**:首先,从源代码仓库获取...

    SpringBoot 学习笔记完整教程

    SpringBoot学习笔记完整教程 SpringBoot是Spring框架的一个简化版,旨在简化Spring应用程序的初始设置和开发过程。它集成了大量的常用库,如数据访问、安全、Web等,使得开发者可以快速构建健壮的微服务应用。本...

    Spring学习笔记(内含代码)

    这个“Spring学习笔记(内含代码)”包含了作者在深入研究Spring框架过程中所做的详细记录,旨在帮助初学者和有经验的开发者更好地理解和应用Spring。 Spring框架的核心特性包括依赖注入(Dependency Injection,DI...

    Directshow(SDK)学习笔记

    如果你使用Visual C++(VC),则需要在项目设置中包含`Dshow.h`头文件和`Strmiids.lib`及`Quartz.lib`库。`Strmiids.lib`包含了所有接口的CLSID和IID定义,而`Quartz.lib`则是必需的库文件。 一个简单的DirectShow...

Global site tag (gtag.js) - Google Analytics