• Quartz学习-- quartz基本介绍和 Cron表达式


    Quartz学习<一>


      目录 

          一. Quartz 大致简介

               二 . Cron 表达式




     

    一. Quartz 大致简介

    1. Quartz 是完全由 java 开发的一个开源任务日程管理系统

      ​任务日程管理系统 换句话说就是:

      ​ 一个预先确定的日程时间到达时,负责执行任务的一个系

    2. Quartz用一个.jar 库文件,其包含了所有Quartz的核心功能,

      1. 这些功能有一个主要的接口: Schedule接口

        它提供了简单的操作 例如:

        ​ 将任务纳入日程或者从日程中取消

        ​ 开始/停止/暂停日程进度

    3. 定时器的种类:

      Quartz中有五中类型的Trigger:

      • SimpleTrigger : 用来触发只需执行一次或者在给定时间触发并且重复N次 且每次执行延迟一定时间的任务

      • CronTrigger : 按照日历触发,例如 每个周五 每个月的1号凌晨 2:30

      • DateIntervalTrigger

      • NthIncludedDayTrigger

      • Calendar 类(org.quartz.Calendar)

    4. 存储方式:

      Quartz自身支持 两种存储方式:

      • RAMJobStore (顾明思议 存放在当前内存)

      • JDBCJobStore (通过jdbc实例到数据库)

      对比:

      存储类型优点缺点
      RAMJobStore 不需要外部数据库,配置简单,运行速度快 因为调度程序信息存储在jvm 所以jvm程序停止运行时 将有丢失 且因为内存大小也有存储个数限制
      JDBCJobStore 可以存储到数据库中可以控制事物 因为需要连接数据库 所以运行速度有所影响
    5. 表关系及解释

      

    表名称 说明
    qrtz_blob_triggers Trigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型,JobStore 并不知道如何存储实例的时候)
    qrtz_calendars 以Blob类型存储Quartz的Calendar日历信息, quartz可配置一个日历来指定一个时间范围
    qrtz_cron_triggers 存储Cron Trigger,包括Cron表达式和时区信息。
    qrtz_fired_triggers 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息
    qrtz_job_details 存储每一个已配置的Job的详细信息
    qrtz_locks 存储程序的非观锁的信息(假如使用了悲观锁)
    qrtz_paused_trigger_graps 存储已暂停的Trigger组的信息
    qrtz_scheduler_state 存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
    qrtz_simple_triggers 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
    qrtz_triggers 存储已配置的 Trigger的信息
    qrzt_simprop_triggers  

     

    1. 核心类和关系

      1. 核心类

        • QuartzSchedulerThread:

          负责执行向QuartzScheduler注册的触发Trigger的工作线程

        • ThreadPool :

          Scheduler使用一个线程作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率

        • QuartzSchedulerResources :

          包含穿件QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)

        • JobStore :

          通过类实现的接口,这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Job和org.quartz.Trigger存储机制.作业和触发器的存储应该以其名称和组的组合为唯一性

        • QuartzScheduler :

          Quartz的核心,他是org.quartz.Scheduler接口的间接实现,包含调度org.quartz.Jobs ,注册org.quartz.JobListener实例等的方法

        • Scheduler :

          这是Quartz Scheduler的主要接口,代表一个独立运行容器. 调度程序维护JobDetails和触发器的注册表.一旦注册,调度程序负责执行作业,当她们的相关连的触发器触发(当她们的预定时间到达时 )

        • Trigger:

          具有所有触发器通用属性的基本接口,描述了job执行的时间触发规则,

          使用TriggerBuilder实例化实际触发器

        • JobDetail :

          传递给定作业实例的详细信息属性.

          JobDetails将使用JobBuilder创建/定义

        • Job :

          表示要执行的"作业"的类的实现接口.

          只有一个方法:

          void execute(JobExecutionContext context);

          (JobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中 )

          Job 有个子接口StatefulJob,代表没有状态任务

          有状态任务不可并发,前次任务没有执行完,后面任务则一直处于阻塞等待状态

      2. 一个job可以被多个Trigger 绑定,但是一个Trigger只能绑定一个job!

    2. quartz.properties Quartz可更改配置

      //调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
      org.quartz.scheduler.instanceName:DefaultQuartzScheduler
      //ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
      org.quartz.scheduler.instanceId :AUTO
      //数据保存方式为持久化
      org.quartz.jobStore.class :org.quartz.impl.jdbcjobstore.JobStoreTX
      //表的前缀
      org.quartz.jobStore.tablePrefix : QRTZ_
      //设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
      //org.quartz.jobStore.useProperties : true
      //加入集群 true 为集群 false不是集群
      org.quartz.jobStore.isClustered : false
      //调度实例失效的检查时间间隔
      org.quartz.jobStore.clusterCheckinInterval:20000
      //容许的最大作业延长时间
      org.quartz.jobStore.misfireThreshold :60000
      //ThreadPool 实现的类名
      org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
      //线程数量
      org.quartz.threadPool.threadCount : 10
      //线程优先级
      org.quartz.threadPool.threadPriority : 5(threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1)
      //自创建父线程
      //org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
      //数据库别名
      org.quartz.jobStore.dataSource : qzDS
      //设置数据源
      org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
      org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz
      org.quartz.dataSource.qzDS.user:root
      org.quartz.dataSource.qzDS.password:123456
      org.quartz.dataSource.qzDS.maxConnection:10
      

        

    3. JDBC插入表顺序

      主要的JDBC操作类,执行sql顺序: 

      基本顺序:
      记录工作内容  
      插入触发器列表  
      对应类型trigger规则入库  
      存储已触发job信息和trigge信息

      Simple_trigger :插入顺序
      qrtz_job_details ---> qrtz_triggers ---> qrtz_simple_triggers
      qrtz_fired_triggers

      Cron_Trigger:插入顺序
      qrtz_job_details ---> qrtz_triggers ---> qrtz_cron_triggers
      qrtz_fired_triggers




      
      

    二 . Cron 表达式

    1. 为什么要使用cron表达式

      我们之前提到 有五种触发器归我们使用

      其中常用的 有 SimpleTrigger 和 CronTrigger

      • SimpleTrigger 是完全指定的时间反复进行工作的时间表

    • CronTrigger 却拥有着 充分的可根据日历预定的 方案 且它包含Simple方案中的 初始启动时间

      例如:

      • 每个星期五中午

      • 每个工作日的早上10:30

      • 周三周五 9:00-10:00 每五分钟一次

    1. Cron Expressions

      Cron 表达式并不是只是使用在 Quartz中的 ,实际上它作为一种专门的表达式也应用在Linux的定时任务中 ,以及在java中Spring的@Scheduled注解 也都使用了

      Cron表达式是 字符串形式

      Cron本质上是由七个 子表达式,描述个别细节的时间表 而这些子表达式是由空格分开的

      子表达式:

      位置意义有效值可用特殊字符
      1 Seconds 0-59 , - * /
      2 Minutes 0-59 , - * /
      3 Hours 0 - 23 , - * /
      4 Day-of-Month 1 - 31 ( 注意一些特别的月份) , - * / ? L W
      5 Month 0 - 11 字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV DEC” , - * /
      6 Day-of-Week(每周) 1 - 7 字符串“SUN, MON, TUE, WED, THU, FRI, SAT”表示 * 注意: 1==SUN , - * / ? L #
      7 Year(年 可选字段) empty 或者 1970-2099 , - * /
      1. 特殊字符

        显然通过子表达式并不能写出一个 重复执行的表达式

        而特殊字符就是来解决当前问题的

      特殊字符 :

      符号表示举例说明
      / 与当前子表达式结合使用占用一个子表达式位置 例: "3/15" 放在第二个子表达式位上, 表示第三分钟开始执行,每15分钟执行一次
      ? 某一天 只存在与 Day-of-Month 和 Day-of-Week 中使用,来解决 这两个表达式的冲突问题 在其中一个子表达式有值的情况下 ?写在另一个表达式上表示匹配任意值,这样我们就不会再用* 去来表示匹配任意值了 例: 每月15号的早上4点 : "0 0 4 15 * ?" 每周五晚上11点: "0 0 23 ? * FRI"
      L 每月 或每周 的最后一天 只存在与 Day-of-Month 和 Day-of-Week 中使用, Day-of-Month 子表达式中,“L”表示一个月的最后一天 Day-of-Week 子表达式中,“L”表示一个星期的最后一天,也就是SAT 例: “0 15 10 ? * 6L” 表示 每月最后一个星期五10:15分运行。 "0 15 10 2L * ?" 表示 每月倒数第二天10:15分运行。
      W 最近工作日 只存在与 Day-of-Month 最近的工作日: 例: "0 15 10 15W * ?" 每个月距离15日最近的工作日 如 15日是周六则执行时间是14日 若15日是周日 则执行时间是16 如15号是工作日就15执行 就近匹配不会跨出当前月
      # 第几个星期几 只存在与 Day-of-Week 中 每月第n个工作日 例:“0 15 10 ? * 6#3” 表示每个月第三个星期五 “0 15 10 ? * 4#2” 表示每个月第二个星期三
      , 多个 例: "0 0 0,13,18,21 * * ?": 每天的0点、13点、18点、21点都执行一次:
      - 区间 例: "0 0-5 14 * * ?" : 在每天下午2点到下午2:05期间的每1分钟触发
      * 补位符 补位 但是 注意: Day-of-Month 和 Day-of-Week 肯定有一个为 ? 也不能两个 ?

      综合例子:

      "0 0/30 0-4 ? 3,7 5#2 2018":

      ​ 30分钟执行一次

      ​ 凌晨的0-4 点

      ​ 每个月

      ​ 3 月和 7月

      ​ 第二个周四

      ​ 2018年

      ​ : 2018年 的三月和7月的第二个周四的凌晨0-4点 开始每30分钟执行一次

      "0 30 4 10LW * ?":

      ​ 第四位是 Day-of-Month L在此表示 每个月最后

      ​ 10L表示每月的倒数第十天 (不一定是21号 月份不同倒数的第几天也就不同 )​ W表示 附近的工作日

      ​ 所以表示每个月离倒数第十天最近的工作日的凌晨4点30分执行一次

  • 相关阅读:
    Android NestedScrolling与分发机制 二
    Android NestedScrolling与分发机制
    Android:View随手指移动
    开发错误记录5-Failed to sync Gradle project ‘HideTitleDemo’
    TouchSlop与VelocityTracker认识
    Android判断Touch为滑动事件还是操作控件
    Android-动画简介
    开发错误记录6----友盟社会化分享与支付宝-微信支付问题
    设计模式之抽象工厂模式
    面试题_抽象工厂,字符反串,冒泡与选择排序
  • 原文地址:https://www.cnblogs.com/wunian7yulian/p/9016073.html
Copyright © 2020-2023  润新知