quartz(二)核心元素介绍

本文深入探讨了Quartz定时任务框架的核心元素:Scheduler、Trigger和JobDetail,以及它们之间的关系。Scheduler作为调度器,通过线程池进行任务调度;Trigger定义任务的触发规则;JobDetail存储任务详情,Job是实际执行体。文章还介绍了Quartz的线程模型、启动流程和misfire处理机制,分析了任务延迟执行的可能原因。
摘要由CSDN通过智能技术生成

quartz核心元素及底层原理介绍

Quartz的核心元素主要有Scheduler、Trigger、Job、JobDetail。其中

  • Scheduler为调度器负责整个定时系统的调度,内部通过线程池进行调度,下文阐述。
  • Trigger为触发器记录着调度任务的时间规则,主要有四种类型:SimpleTrigger、CronTrigger、DataIntervalTrigger、NthIncludedTrigger,在项目中常用的为:SimpleTrigger和CronTrigger。
  • JobDetail为定时任务的信息载体,可以记录Job的名字、组及任务执行的具体类和任务执行所需要的参数
  • Job为任务的真正执行体,承载着具体的业务逻辑。

元素之间的关系如下:

介绍:先由SchedulerFactory创建Scheduler调度器后,由调度器去调取即将执行的Trigger,执行时获取到对于的JobDetail信息,找到对应的Job类执行业务逻辑。

quartz中线程主要分为执行线程和调度线程。

  • 执行线程主要由一个线程池维护,在需要执行定时的时候使用
  • 调度线程主要分为regular Scheduler Thread和Misfire Scheduler Thread;其中Regular Thread 轮询Trigger,如果有将要触发的Trigger,则从任务线程池中获取一个空闲线程,然后执行与改Trigger关联的job;Misfire Thraed则是扫描所有的trigger,查看是否有错失的,如果有的话,根据一定的策略进行处理。

quartz启动流程

当服务器启动时,Spring就加载相关的bean。SchedulerFactoryBean实现了InitializingBean接口,因此在初始化bean的时候,会执行afterPropertiesSet方法,该方法将会调用SchedulerFactory(DirectSchedulerFactory 或者 StdSchedulerFactory,通常用StdSchedulerFactory)创建Scheduler。我们在SchedulerFactoryBean配置类中配了相关的配置及配置文件参数,所以会读取配置文件参数,初始化各个组件。关键组件如下:

  • ThreadPool:既上面所说的执行线程,一般是使用SimpleThreadPool(线程数量固定的线程池),SimpleThreadPool创建了一定数量的WorkerThread实例来使得Job能够在线程中进行处理。WorkerThread是定义在SimpleThreadPool类中的内部类,它实质上就是一个线程。在SimpleThreadPool中有三个list:workers-存放池中所有的线程引用,availWorkers-存放所有空闲的线程,busyWorkers-存放所有工作中的线程;配置如下
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=3
org.quartz.threadPool.threadPriority=5
  • JobStore初始化定时任务的数据存储方式,分为两种:存储在内存的RAMJobStore和存储在数据库的JobStoreSupport(包括JobStoreTX和JobStoreCMT两种实现,JobStoreCMT是依赖于容器来进行事务的管理,而JobStoreTX是自己管理事务),若要使用集群要使用JobStoreSupport的方式;
  • QuartzSchedulerThread初始化调度线程,在初始化的时候paused=true,halted=false,虽然线程开始运行了,但是paused=true,线程会一直等待,直到start方法将paused置为false;SchedulerFactoryBean还实现了SmartLifeCycle接口,因此初始化完成后,会执行start()方法,该方法将主要会执行以下的几个动作:
  1. 创建ClusterManager线程并启动线程:该线程用来进行集群故障检测和处理
  2. 创建MisfireHandler线程并启动线程:该线程用来进行misfire任务的处理
  3. 置QuartzSchedulerThread的paused=false,调度线程才真正开始调度

整个启动流程图如下:
quartz启动时序图

流程图简要说明:

  1. 先读取配置文件
  2. 初始化SchedulerFactoryBean
  3. 初始化SchedulerFactory
  4. 实例化执行线程池(TheadPool)
  5. 实例化数据存储
  6. 初始化QuartzScheduler(为Scheduler的简单实现,包括调度作业、注册JobListener实例等方法。)
  7. new一个QuartzSchedulerThread调度线程(负责执行在QuartzScheduler中注册的触发触发器的线程。),并开始运行
  8. 调度开始,注册监听器,注册Job和Trigger
  9. SchedulerFactoryBean初始化完成后执行start()方法
  10. 创建ClusterManager线程并启动线程
  11. 创建MisfireHandler线程并启动线程
  12. 置QuartzSchedulerThread的paused=false,调度线程真正开始调度,开始执行run方法

QuartzSchedulerThread逻辑具体介绍:

类中主要的方法就是run方法,下面主要对run方法进行介绍:

 //只有当Quartzscheduler执行start方法时被调用
 void togglePause(boolean pause) {
   
        synchronized(this.sigLock) {
   
            this.paused = pause;
            if (this.paused) {
   
                this.signalSchedulingChange(0L);
            } else {
   
                this.sigLock.notifyAll();
            }

        }
    }
public void run() {
   
        boolean lastAcquireFailed = false;

        label214:
        //此处判断调度器是否终止
         while(!this.halted.get()) {
   
                    try {
   
                        synchronized(this.sigLock) {
   
                            //此处判断调度器是否终止或是否暂停,由于我们在初始化的时候
                            //将paused=true,那么调度线程此时不会真正开始执行只会在不断循环阻塞
         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值