Quartz 任务调度框架源码阅读解析

概念: quartz 是一个基于JAVA的定时任务调度框架

案例: 


        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>


        JobDetail job = JobBuilder.newJob(SchedulerTs.class)
                .withIdentity("job1", "group1")
                .usingJobData("name", "zs")
                .build();
        Date endDate = DateUtils.addMinutes(new Date(), 2);
        SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger", "triggerGroup")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        // 任务执行间隔
                        .withIntervalInSeconds(10)
                        // 重复执行次数
                        .withRepeatCount(10))
                .forJob(job)
                .endAt(endDate)
                .startNow()
                .build();


        StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();

        Scheduler scheduler = stdSchedulerFactory.getScheduler();
        // 配置任务
        scheduler.scheduleJob(job, trigger);
        scheduler.start();

使用、上手难度: 简单

效果已经实现了、那么这个是怎么实现的呢、很费解、所以花了一早上时间扒了扒源码、解惑

首先介绍几个关键的类: 


        StdSchedulerFactory 调度工厂、Scheduler 调度工具(类)、QuartzSchedulerThread 任务执行线程、SchedulerRepository 单例的调度仓库 、 JobDetail 任务job封装接口、SimpleTrigger 触发器

        现在看着有点多、记不住. 蓝色部分忽略、他只是建造者模式的应用、封装了 很多属性方法、SchedulerRepository 单例的调度仓库 也可以忽略、他只是一个map 用来存放 调度类的,并且也能够避免相同调度类的重复创建;

        重头戏: 找到切入点 StdSchedulerFactory 调度工厂 是如何获取到 调度类 Scheduler 的,并且 Scheduler.start   scheduleJob 方法做了什么,我认为看懂这两块,基本就算差不多了

        创建 StdSchedulerFactory 对象,只是一个空对象,什么也没有做、关键点在于StdSchedulerFactory 的 getScheduler  方法, 我们先看源码

        到现在比较明了了. 主要工作在 initialize 方法 和 instantiate 方法做的,我们逐个分析
        initialize 源码.只粘贴关键代码. 实际上他也只是做了文件解析、将文件中的配置信息交给Properties,然后将 配置信息交给 工厂类的属性 cfg 对象.这个对象只是在properties 外面封装了一层.本质还是一个properties、配置信息包含一些线程数、执行间隔啥的. 这个就是配置、具体不做讨论

        instantiate 源码、这个方法做的 任务比较多、涉及到 QuartzSchedulerThread 类的创建和启动、调度仓库调度器的插入、前面的配置信息就是在这一步装配到任务上的,废话不多说、直接看源码

        现在又会有一个疑惑、一个线程执行一次就结束了、他怎么做到一直监听到有新任务进来的呢? 关键在于 一个while 循环 和 sigLock 对象的 awaitnotifyAll 操作,下面图放了 这个线程run方法的动作, 到现在已经明确 instantiate 执行完之后线程就是已经启动的了

        现在我们再去看看 StdSchedulerFactory 的 scheduleJob 方法做了啥,将当前任务 保存到了 triggersByKey 和 jobsByKey 中 ,然后 交给了 listener 和 plugs 监听处理

        最后一步、启动 StdSchedulerFactory.start

        通过 sigLocknotifyAll 通知 quartzSchedulerThread 线程继续执行.

        自己实现的任务是在何时被调用的呢? QuartzSchedulerThread::run 来寻找答案

        新建的shell 是一个线程、initialize 关键步骤,newJob

        找到了、反射 实例话 job类、得到了我们写好的对象
        runThread(shell) 执行了 shell 线程,run方法做了什么 我们看下,job.execute 任务被执行了.
完美,我看到的是这样如果有疏漏麻烦评论区指正,感激,结尾附上思维导图、相对来说更加详细

  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值