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部署lnmp 实战 (多注意配置文件,不管访问试试换个浏览器)

    Docker部署LNMP环境 关闭防火墙,设置自定义网络 systemctl stop firewalld systemctl disable firewalld setenforce 0 docke ...

  2. 【CF1194F】Crossword Expert(数学 期望)

    题目链接 大意 给你\(N\)个事件,解决每个事件所需的时间有\(1/2\)的概率为\(t[i]\),\(1/2\)的概率为\((t[i]+1)\),给你总时间\(T\),在\(T\)时间内按顺序解决 ...

  3. Ansible playbook实现apache批量部署,并对不同主机提供以各自IP地址为内容的index.html

    1.基于key验证免密授权 1.1 生成kekgen # ssh-keygen Generating public/private rsa key pair. Enter file in which ...

  4. MySQL5.7 库、表结构、表字段的查询、更改操作

    1.查询所有数据库 SHOW DATABASES; 2.查询库中所有表 写法1: ① USE [DATABASE_NAME]; ② SHOW TABLES; 写法2: SHOW TABLES FROM ...

  5. Springboot整合ElasticSearch进行简单的测试及用Kibana进行查看

    一.前言 搜索引擎还是在电商项目.百度.还有技术博客中广泛应用,使用最多的还是ElasticSearch,Solr在大数据量下检索性能不如ElasticSearch.今天和大家一起搭建一下,小编是看完 ...

  6. Solution -「CF 840C」On the Bench

    \(\mathcal{Description}\)   Link.   给定数列 \(\{a_n\}\),求排列 \(\{p_n\}\) 的个数,使得 \((\forall i\in[1,n))(a_ ...

  7. suse 12 双网卡bonding模式

    文章目录 工欲善其事,必先配静态ip 网卡bonding eth0 eth1 192.168.70.52 192.168.70.55 工欲善其事,必先配静态ip 重要的事情说三遍 修改配置之前,先备份 ...

  8. 如何将k8s中的某些节点单独、仅给某些应用来使用

    1.概述 在k8s集群的使用场景中有这样的一种情况,某些机器只给某些特殊的应用来使用.那么,这个时候,需要有以下的2个条件来进行保障: 节点不允许其他的pod来使用 应用只允许被调度到该节点上 2.实 ...

  9. BI数据可视化工具怎么选?用这款就够了!

    任何一项产品的选择都需要谨慎而全面,BI数据可视化工具的选择就更不用说了.作为企业的IT部门,如果没有良好的BI工具支持,IT部门将会十分容易陷入困境.那么面对多元化的BI工具市场,IT部门该如何选择 ...

  10. HashMap常用方法(简版)

    HashMap继承自Map,是一个散列表,它的存储形式是键-值对,键值对的类型可以不一样,这是它相较数组方便的一点. 1.put()方法 哈希表.put(key,value): 该方法用于将键值对加入 ...