调度介绍 - Quartz是怎么调起来的

简介: Quartz调度核心类QuartzSchedulerThread,是一个线程。在线程启动后,通过while循环不断去触发作业的执行。ps:源码版本2.3.2,

1.前言

上篇文章,我们介绍了quartz的调度过程及关键类。我们知道quartz作为一个调度框架,调度是框架的核心。
由上篇我们知道,在Job被调用之前,经过了几个过程,调度器启动,调度器将job和trigger加入调度器。之后就发现作业被调度了。这里再思考一下调度背后是什么?如果让我们去实现一个调度该怎么做。


2.正文

上文中Scheduler是通过Spring注入的,我们没法了解Scheduler的初始化过程。所以,我们找了个官方示例,示例中可以看到在Job被调度之前有如下3行代码:

SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();

Scheduler sched = schedFact.getScheduler();

sched.start();

第一行,源码中StdSchedulerFactory的无参构造方法是个空方法,不管他。
第二行,schedFact.getScheduler()方法非常关键,该方法中初始化了QuartzScheduler,并返回了Scheduler。
第三行,调度器调用start()方法,开始启动。

2.1 调度准备

多图预警

第一,我们可以看到QuartzScheduler在初始化的时候,初始化并启动了调度线程QuartzSchedulerThread,并且该线程的标识halted = false,paused = true。源码截图如下:
1.png
2.png
3.png
7.png

第二,我们看类之间的关系。StdScheduler是Scheduler的实现类,也是QuartzScheduler的代理类。
由此我们可知,Scheduler的start()方法实际是调用了QuartzScheduler的start()方法。而start()方法中将调度线程QuartzSchedulerThread的paused = false。也就是说退出了while循环里嵌套的while,线程开始向下运行。源码截图如下:
4.1.png
4.png
5.png
5.5.png
6.png

以上是quartz调度前的准备工作。
小结:QuartzSchedulerThread线程启动后,run方法开始运行,因为halted = false故进入第一个while循环,因为halted = false,paused = true接着会进入第二个while循环,第二个循环wait-wait-wait......不停的wait,一直等到start()方法将paused设置为false。则退出嵌套的循环,开始往下运行,而往下才开始真正的调度。

2.2 准备完成,开始调度

先看一下run方法全貌:
9png.png
总体可以分为三块,前后两个同步代码块,中间夹杂了一些代码。第一个同步代码块就是刚才的嵌套while循环,用于等待调度启动,而另外一个功能类似,也是等待。这里我们重点关注的是中间的部分,图片中红框标注的。变量availThreadCount由名称可以知道,是线程池当前可用的线程数量。availThreadCount如果大于0则进入if分支执行,然后contine。这里好理解,就是去确认下当前是否有可用线程,如果有则开始进入调度逻辑。这部分代码挺长从279行到414行,我们截取关键部分看一下:
第一步,查询即将到触发时间的trigger
11.png
第二步,判断trigger是否到时间
10.png
第三步,标记trigger已触发
12png.png
第四步,通过线程池执行Job
13.png
最后,下一轮while循环。

2.3 小结

调度线程QuartzSchedulerThread进入while的无限循环,查询JobStore中即将到期的trigger,判断trigger是否到达触发时间,如果到达则通过线程池异步执行trigger绑定的Job。

3. 后记

Quartz作为一个调度框架,提供的丰富的特性,也是基于此源码量多也杂。但是作为一个调度框架核心逻辑仍是调度,我们这里通过看源码,略微一窥他调度的背后是什么。
以下是看源码时,觉得比较关键的类

  • Scheduler:调度器接口。
  • QuartzScheduler:真正调度器的实现,提供了调度器的启停、作业增删等丰富的功能。
  • StdScheduler:调度器的官方实现,实现了Scheduler,也是QuartzScheduler的代理类。
  • QuartzSchedulerThread:核心调度线程,也就是他马不停蹄的去运行Job。
  • ThreadPool:官方的线程池,用于执行Job。
  • JobRunShell:持有TriggerFiredBundle,TriggerFiredBundle持有JobDetail。JobRunShell是一个线程的实现,会真正的调用Job的execute(JobExecutionContext context)方法。

如果对你有bangz帮助,点个赞再走吧

相关文章
|
11月前
|
调度
|
存储 监控 算法
Xxljob调度机制
时间轮算法,其实很简单,就是用实际的时钟刻度槽位来存储任务。 时钟刻度可以更细致,比如把一天切分成246060个秒的刻度,秒的刻度上挂任务。
608 0
Xxljob调度机制
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
调度介绍 - Quartz
众所周知,Quartz作为知名的企业级调度框架,提供了丰富的特性。本文通过一个简单的示例,介绍下quartz在springboot的应用和quartz部分基本概念,并展示了quartz调度作业的基本过程。
调度介绍 - Quartz
Quartz3定时任务学习之异步调度器
Quartz3定时任务学习之异步调度器 Quartz3与Quartz2的主要区别有两点: 1,Quartz3将它的资源类库拆的更细了,比如,想使用Quartz3开发,最少要引用Quartz,Quartz.Jobs,Quartz.Plugins这三个类库。 2,Quartz3整体上使用的是异步创建实例,所以我们使用时就必须要async,await的语法。 下面我们用Quartz3来做一个任务调度。
Quartz3定时任务学习之异步调度器
|
关系型数据库 Java 数据库连接
spring框架使用Quartz执行定时任务实例详解
版权声明:本文为博主原创文章,如需转载,请标明出处。 https://blog.csdn.net/alan_liuyue/article/details/80382324 Quartz简介   1.Quartz,是一个完全由java编写的开源作业调度框架。
1149 0
|
数据可视化 Java 调度
基于Quartz的调度系统 - Marble
实际项目中需要用到JOB的场景非常多,通常需要JOB的业务都需要如下基本功能: 1)集群环境单实例调度; 2)JOB可视化启停; 3)JOB频率可视化配置; 单应用使用JOB开发适配的需求的调度功能过滤繁琐,开销太大,考虑提供统一的调度系统对外提供JOB的调度服务。
11254 0