Quartz --- 入门简介

一、Quartz概述

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是一个完全由Java编写的开源的任务日程管理系统,这个系统可以与任何其他软件系统集成或者一起使用。Quartz相当轻量,并且需要非常少的步骤/配置。Quartz具有容错性,并且可以在系统重启的时候持久化被纳入日程的任务。


Quartz下载地址:

http://www.quartz-scheduler.org/downloads/


Quartz特点:

  • Quartz能嵌入到任何独立的应用中运行。
  • Quartz能在应用服务器或者Servlet容器中实例化,并且能够参与XA事务
  • Quartz能够独立的方式运行,可以通过RMI使用Quartz
  • Quartz可以被实例化为独立程序的集群(有负载均衡和容错能力)


二、Quartz体系结构

2.1 Job:是一个接口,只定义一个方法execute(JobExecutionContext context),在实现接口的execute方法中编写所需要定时执行的Job(任务), JobExecutionContext类提供了调度应用的一些信息。Job运行时的信息保存在JobDataMap实例中;


2.2 JobDetail:
Quartz每次调度Job时, 都重新创建一个Job实例, 所以它不直接接受一个Job的实例,相反它接收一个Job实现类(JobDetail:描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息),以便运行时通过newInstance()的反射机制实例化Job。 


2.3 Trigger:
是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger、CronTrigger这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案


2.4 Calendar:org.quartz.Calendar和java.util.Calendar不同, 它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。 一个Trigger可以和多个Calendar关联, 以便排除或包含某些时间点。

假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。针对不同时间段类型,Quartz在org.quartz.impl.calendar包下提供了若干个Calendar的实现类,如AnnualCalendar、MonthlyCalendar、WeeklyCalendar分别针对每年、每月和每周进行定义;


2.5 Scheduler:代表一个Quartz的独立运行容器, Trigger和JobDetail可以注册到Scheduler中, 两者在Scheduler中拥有各自的组及名称, 组及名称是Scheduler查找定位容器中某一对象的依据, Trigger的组及名称必须唯一, JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法, 允许外部通过组及名称访问和控制容器中Trigger和JobDetail。

Scheduler可以将Trigger绑定到某一JobDetail中, 这样当Trigger触发时, 对应的Job就被执行。一个Job可以对应多个Trigger, 但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例;

2.6 ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

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

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

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

Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。

Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。

图1描述了Scheduler的内部组件结构,SchedulerContext提供Scheduler全局可见的上下文信息,每一个任务都对应一个JobDataMap,虚线表达的JobDataMap表示对应有状态的任务:



三、简单入门案例

3.1 引入Quartz依赖的jar

<dependencies>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>
    </dependencies>

3.2 定义简单Job

public class HelloJob implements Job {

    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 编写工作任务
        System.out.println("Hello, Quartz !!!");
    }
}

3.3 设置触发器

public class SchedulerTest {

    public static void main(String[] args) throws SchedulerException {

        // 通过StdSchedulerFactory获取一个默认的Scheduler调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 定义一个工作对象,绑定Job的实现类
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();

        // 定义简单的触发器
        //Trigger trigger = TriggerBuilder.newTrigger()
        //        .withIdentity("trigger1", "group1").startNow()
        //        .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
        //        .build();


        // 定义基于Corn表达式的触发器,每5秒触发一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1").startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
                .build();

        // 把作业和触发器注册到任务调度中
        scheduler.scheduleJob(jobDetail,trigger);

        // 开启定时器任务
        scheduler.start();

        // 关闭定时器任务
        //scheduler.shutdown();
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz Scheduler是一个功能强大的开源任务调度器。它允许你在特定的时间间隔或在特定的时间点执行任务。Quartz Scheduler可以通过配置文件进行自定义设置和配置。 在Quartz Scheduler的配置中,有一些重要的属性可以调整和配置。引用中提到了一些默认的配置属性,比如计划程序的名称、是否使用RMI进行远程调用、是否将作业执行包装在用户事务中等。此外,还有一些与线程池相关的属性,如线程池中的线程数量、线程优先级等。还有一个重要的属性是jobStore.class,它指定了作业和触发器信息的存储方式,默认是保存在内存中。 引用提到了一些与查询下一个触发器相关的属性,例如misfireThreshold、idleWaitTime、batchTriggerAcquisitionMaxCount和batchTriggerAcquisitionFireAheadTimeWindow。这些属性可以影响查询触发器的条件和查询语句的生成。 引用中还提到了一些与SchedulerThread相关的属性,例如scheduler.threadName、scheduler.makeSchedulerThreadDaemon和scheduler.threadsInheritContextClassLoaderOfInitializer。这些属性用于配置Scheduler持有的QuartzSchedulerThread的线程名称、是否将线程设置为守护线程以及是否在初始化器的ClassLoader中集成。 综上所述,Quartz Scheduler是一个非常灵活和可配置的任务调度器,可以根据需要进行各种属性的设置和配置。通过调整这些属性,可以实现对任务调度的精细控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Quartz-scheduler 定时器概述、核心 API 与 快速入门](https://blog.csdn.net/wangmx1993328/article/details/105057405)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Quartz Scheduler](https://blog.csdn.net/chen517611641/article/details/88929959)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值