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. 清除git中缓存的凭证(用户名及密码)

    今天刚接触Git,还有Gitstack,然后在克隆Gitstack服务器上的仓库时出现了一直用户身份识别失败问题,找了一些大佬的文章才知道原因在于密码输入错误过多.那么如何重新输入呢? 需要清空本地的 ...

  2. php截取字符串,避免乱码

    转载请注明来源:https://www.cnblogs.com/hookjc/ 1. 截取GB2312中文字符串 <?php//截取中文字符串 function mysubstr($str, $ ...

  3. js注释和数据类型转换

    单行注释 用来描述下面一个或多行代码的作用 // 这是一个变量var name = 'hm'; 多行注释 用来注释多条代码 /*var age = 18;var name = 'zs';console ...

  4. 恶补Java Swing线程刷新UI机制(由浅到深的参考大佬博文)

    1. java中进度条不能更新问题的研究 感谢大佬:https://blog.csdn.net/smartcat86/article/details/2226681 为什么进度条在事件处理过程中不更新 ...

  5. Nodejs中调用系统命令、Shell脚本的方法和实例

    每种语言都有自己的优势,互相结合起来各取所长程序执行起来效率更高或者说哪种实现方式较简单就用哪个,nodejs是利用子进程来调用系统命令或者文件,文档见http://nodejs.org/api/ch ...

  6. Jenkins--持续集成及Jenkins介绍

    Jenkins--持续集成及Jenkins介绍 目录 Jenkins--持续集成及Jenkins介绍 一.持续集成及Jenkins介绍 1. 软件开发生命周期 1.1 需求分析 1.2 设计 1.3 ...

  7. pytorch学习

    1 torch.hub torch.hub是一个包含计算机视觉和自然语言处理领域的诸多经典模型调用中心API 我没有运行成功代码 https://blog.csdn.net/qq_38410428/a ...

  8. 系统基础优化( 创建yum私有仓库最详细操作及解释 )

    目录 系统基础优化 一.Linux中安装软件的方式 安装方式 三种安装方式的区别 二.RPM安装☆ 1.安装及其他命令 2.手动下载软件包,可将其拖入shell中自动传入 1).手动网页下载软件包 2 ...

  9. spring boot全局配置文件优先级

    前两篇介绍的application配置文件,即为spring boot全局配置文件.那么spring boot加载配置文件的时候,怎么确定加载哪个目录下哪个文件呢? spring boot默认的配置文 ...

  10. 如何把Spring学精通了?

    作为 Java 后端工程师,几乎都要用到 Spring,今天这篇文章是和大家说说如何学好 Spring. 在之前的一篇 Java 读书路线的文章中,我介绍过 Spring 的读书路线: 虽然 Spri ...