QuartzSchedulerThread

本篇博文,博主将介绍QuartzSchedulerThread的相关内容。话不多说,直接进入正题。

什么是QuartzSchedulerThread?

从源码和该类的名称上,QuartzSchedulerThread首先是一个线程类,因此它继承了Thread类。从这一点上看,代码的自解释性非常重要。

从quartz框架整体上而言,QuartzSchedulerThread相当于管理者线程,它从JobStore中获取需要触发的任务,交给ThreadPool线程池去分配。接着ThreadPool线程池则会从空闲的工作者线程集合中选取一个工作者线程,把任务分配给该线程执行。

属性定义

  1. qs,QuartzScheduler对象的引用
  2. qsRsrcs,QuartzSchedulerResources对象的引用
  3. sigLock,信号锁
  4. signaled,是否有信号
  5. signaledNextFireTime,信号通知后的下一次触发时间
  6. paused,是否暂停
  7. halted,是否停止
  8. random,随机数
  9. idleWaitTime,空闲等待时间,也就是QuartzShedulerThread在处理完一批Job之后,会进行等待的时间(这期间如果没有信号通知它的话)
  10. ...

togglePause方法

QuartzShedulerThread对象在实例化的时候,此时就处于paused状态(paused为ture)。为什么实例化的时候就处于paused状态呢,因为如果此时没有对应的触发器和Job加入到JobStore的话,QuartzShedulerThread执行主逻辑会占用和消耗资源(比如锁的抢占,无效的查询等)。

那么什么时候QuartzShedulerThread才不处于paused状态呢?我们查看源码可知,在quartzSheduler准备好需要对应的资源后,并且在它的start方法调用的时候,quartzSheduler就会调用QuartzShedulerThread的togglePause方法。不知道细心的小伙伴有没有发现,quartzSheduler的start方法,就是对应设计模式中的外观模式。togglePause逻辑如下:

  1. 获取sigLock锁。
  2. 设置paused为传入的值。
  3. 如果传入的值为false,则通知所有等待在sigLock上的线程。
  4. 如果传入的值为true。
  5. 设置signaled为true。
  6. signaledNextFireTime为0。
  7. 通知所有等待在sigLock上的线程。

halt方法

在quartzScheduler停止的时候会调用quartzSchedulerThread的halt方法,也就是去修改quartzSchedulerThread的循环标志halted为false。halt方法逻辑如下:

  1. 获取sigLock锁。
  2. 设置halted为true。
  3. 判断当前quartzSchedulerThread是否处于paused状态,如果处于paused状态就直接通知等待在该sigLock锁上的所有线程。
  4. 如果不处于paused状态,那么就需要通知quartzSheduler的主处理逻辑发生重大变化,此时signaled为true, signaledNextFireTime时间为0。
  5. 如果传入的wait值为true,会调用quartzSchedulerThread的join方法。(也就是需要把当前线程执行完毕,调用者线程才能继续执行。)

run方法

run方法是quartzSchedulerThread的主处理逻辑。它的方法逻辑如下:

  1. 首先是一个while循环,循环标记是halt。这个是线程长时间运行的处理套路。
  2. 判断当前是否处于paused状态,并且halt为false。如果是的话,则需要进行有条件等待( sigLock.wait(1000L))。
  3. 如果此时从sigLock唤醒时,halted值为false,那么应该直接跳出循环,
  4. 接着阻塞式的获取线程池中可用的空闲线程数。如果可用线程数大于0才继续执行。
  5. 接着从JobStore中获取一定时间范围内(now+idleWaitTime)的触发器。
  6. 如果触发器个数大于0,则获取trigger集合的第一个元素,然后阻塞式判断它的下一次触发时间与当前时间之差是否少于2毫秒。
  7. 如果小于2毫秒的话,判断当前quartzSchedulerThread是否处于halted状态。
  8. 如果当前不处于halted状态,则调用对应JobStore的triggersFired方法。
  9. 接着实例化JobRunShell,并传入线程池进行分配。
  10. 最后quartzSchedulerThread就进行有时间的等待(随机等待一个时间,时间值小于idleWaitTime)。

博主微信公众号

quartz框架(十)-QuartzShedulerThread的更多相关文章

  1. Quartz 框架 教程(中文版)2.2.x

    Quartz 框架 教程(中文版)2.2.x 之第一课 开始使用Quartz框架 Quartz 框架 教程(中文版)2.2.x 之第二课 Quartz API,Jobs和Triggers简介 Quar ...

  2. Quartz框架(第一版)

    任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...

  3. Quartz框架

    Quartz框架 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制.Quartz 允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和触发器的多 ...

  4. 【淘淘】Spring整合Quartz框架

    我在外面工作实习的时候,我们做的项目是一个日报子系统,也就是定时定点为公司生成一些报表数据还有一些数据反馈.这时候我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.当时,我做 ...

  5. java任务调度quartz框架的小例子

    quartz是一个开源的作业调度框架,当然,java可以使用Timer来实现简单任务调度的功能,但Timer是单线程的设计方案,使得一个任务延迟会影响到其他的任务.java也可以使用Scheduled ...

  6. Quartz框架简介

    一.Quartz概述: Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间.其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高 ...

  7. [译]Quartz 框架 教程(中文版)2.2.x 之第一课 开始使用Quartz框架

    第一课:开始使用Quartz框架 在你使用调度器之前,需要借助一些具体的例子去理解(谁愿意只是猜啊?).你可以使用SchedulerFactory类来达到程序调度的目的.有一些Quartz框架的用户可 ...

  8. Spring框架下的定时任务quartz框架的使用

    手头的这个项目需要用到定时任务,但之前没接触过这东西,所以不太会用,从网上找资料,大致了解了一下,其实也不难.Java的定时任务实现有三种,一种是使用JDK自带的Timer那个类来实现,另一种是使用q ...

  9. Quartz框架学习(1)—核心层次结构

    Quartz框架学习 Quartz(任务调度)框架的核心组件: job:任务.即任务调度行为中所要调度的对象. trigger:触发器.是什么促使了一个任务的调度?当然是时间.这也算事件驱动类型程序. ...

随机推荐

  1. Docker入门 安装 基础操作命令

    Docker 学习来源 https://www.bilibili.com/video/av26993050/?spm_id_from=333.788.b_636f6d6d656e74.20 https ...

  2. ajax、axios、fetch区别及优缺点

    将jQuery的ajax.axios和fetch做个简单的比较,所谓仁者见仁智者见智,最终使用哪个还是自行斟酌 1.jQuery ajax $.ajax({ type: 'POST', url: ur ...

  3. 运行时异常&编译时异常

    /* 异常体系: --------| Throwable 所有错误或者异常的父类 --------------| Error(错误) --------------| Exception(异常) 异常一 ...

  4. JavaScript中this的绑定规则

    JavaScript中this的绑定规则 前言 我们知道浏览器运行环境下在全局作用域下的this是指向window的,但是开发中却很少在全局作用域下去使用this,通常都是在函数中进行使用,而函数使用 ...

  5. 带你十天轻松搞定 Go 微服务之大结局(分布式事务)

    序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务 RPC 服务 Auth 验证 ...

  6. Ubuntu20.04.3中telnet 127.0.0.1时Unable to connect to remote host: Connection refused

    本博客旨在自我学习使用,如有任何疑问请及时联系博主 今天遇到个稀奇古怪的问题: 调试emqx的时候一直econnrefused,检查服务时,突然发现在ubuntu上telnet localhost竟然 ...

  7. socket 套接字编程

    今日内容 socket 套接字编程 简易服务端与客户端代码实现 通信循环 黏包现象(TCP协议) 报头制作.struct 模块.封装形式 内容详细 一.socket 套接字编程 实现一款能够进行数据交 ...

  8. Solution -「多校联训」I Love Random

    \(\mathcal{Description}\)   给定排列 \(\{p_n\}\),可以在其上进行若干次操作,每次选取 \([l,r]\),把其中所有元素变为原区间最小值,求能够得到的所有不同序 ...

  9. mysql对属性的增删改

    修改表 alter table 创建表db 查看表 desc与describe desc table 查看建表语句show create table t1; 修改表名 alter table t1 r ...

  10. Dump Lsass内存转储新旧方法

      之前看到一篇关于Lsass内存dump的文章,学习记录一下.   lsass.exe(Local Security Authority Subsystem Service)进程空间中,存有着机器的 ...