实现quartz定时器及quartz定时器原理介绍

 更新时间:2013年12月10日 10:12:32   作者:  
Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便,下面我们看看如何使用它

一、核心概念
 
Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可。

1、Job
表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context)

2、JobDetail
JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。

3、Trigger代表一个调度参数的配置,什么时候去调。

4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。

二、一个最简单入门实例

复制代码 代码如下:

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;

/**
* quartz定时器测试
*
* @author leizhimin 2009-7-23 8:49:01
*/
public class MyJob implements Job {
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
                System.out.println(new Date() + ": doing something...");
        }
}

class Test {
        public static void main(String[] args) {
                //1、创建JobDetial对象
                JobDetail jobDetail = new JobDetail();
                //设置工作项
                jobDetail.setJobClass(MyJob.class);
                jobDetail.setName("MyJob_1");
                jobDetail.setGroup("JobGroup_1");

                //2、创建Trigger对象
                SimpleTrigger strigger = new SimpleTrigger();
                strigger.setName("Trigger_1");
                strigger.setGroup("Trigger_Group_1");
                strigger.setStartTime(new Date());
                //设置重复停止时间,并销毁该Trigger对象
                java.util.Calendar c = java.util.Calendar.getInstance();
                c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L);
                strigger.setEndTime(c.getTime());
                strigger.setFireInstanceId("Trigger_1_id_001");
                //设置重复间隔时间
                strigger.setRepeatInterval(1000 * 1L);
                //设置重复执行次数
                strigger.setRepeatCount(3);

                //3、创建Scheduler对象,并配置JobDetail和Trigger对象
                SchedulerFactory sf = new StdSchedulerFactory();
                Scheduler scheduler = null;
                try {
                        scheduler = sf.getScheduler();
                        scheduler.scheduleJob(jobDetail, strigger);
                        //4、并执行启动、关闭等操作
                        scheduler.start();

                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
//                try {
//                        //关闭调度器
//                        scheduler.shutdown(true);
//                } catch (SchedulerException e) {
//                        e.printStackTrace();
//                }
        }
}

执行结果:


当把结束时间改为:

复制代码 代码如下:

//设置重复停止时间,并销毁该Trigger对象
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L);
strigger.setEndTime(c.getTime());

执行结果:

当添加一条关闭调度器的语句:
//4、并执行启动、关闭等操作
scheduler.start();
scheduler.shutdown(true);


程序执行结果:
Thu Jul 23 10:11:50 CST 2009: doing something...

Process finished with exit code 0
仅仅执行了一次,这一次能执行完,原因是设定了scheduler.shutdown(true);true表示等待本次任务执行完成后停止。

从这里也可以看出,scheduler是个容器,scheduler控制jobDetail的执行,控制的策略是通过trigger。

当scheduler容器启动后,jobDetail才能根据关联的trigger策略去执行。当scheduler容器关闭后,所有的jobDetail都停止执行。

三、透过实例看原理

通过研读Quartz的源代码,和本实例,终于悟出了Quartz的工作原理。

1、scheduler是一个计划调度器容器(总部),容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就班自动去执行。

2、JobDetail是一个可执行的工作,它本身可能是有状态的。

3、Trigger代表一个调度参数的配置,什么时候去调。

4、当JobDetail和Trigger在scheduler容器上注册后,形成了装配好的作业(JobDetail和Trigger所组成的一对儿),就可以伴随容器启动而调度执行了。

5、scheduler是个容器,容器中有一个线程池,用来并行调度执行每个作业,这样可以提高容器效率。

6、将上述的结构用一个图来表示,如下:
 


四、总结

1、搞清楚了上Quartz容器执行作业的的原理和过程,以及作业形成的方式,作业注册到容器的方法。就认识明白了Quartz的核心原理。

2、Quartz虽然很庞大,但是一切都围绕这个核心转,为了配置强大时间调度策略,可以研究专门的CronTrigger。要想灵活配置作业和容器属性,可以通过Quartz的properties文件或者XML来实现。

3、要想调度更多的持久化、结构化作业,可以通过数据库读取作业,然后放到容器中执行。

4、所有的一切都围绕这个核心原理转,搞明白这个了,再去研究更高级用法就容易多了。

5、Quartz与Spring的整合也非常简单,Spring提供一组Bean来支持:MethodInvokingJobDetailFactoryBean、SimpleTriggerBean、SchedulerFactoryBean,看看里面需要注入什么属性即可明白了。Spring会在Spring容器启动时候,启动Quartz容器。

6、Quartz容器的关闭方式也很简单,如果是Spring整合,则有两种方法,一种是关闭Spring容器,一种是获取到SchedulerFactoryBean实例,然后调用一个shutdown就搞定了。如果是Quartz独立使用,则直接调用scheduler.shutdown(true);

7、Quartz的JobDetail、Trigger都可以在运行时重新设置,并且在下次调用时候起作用。这就为动态作业的实现提供了依据。你可以将调度时间策略存放到数据库,然后通过数据库数据来设定Trigger,这样就能产生动态的调度。

相关文章

  • Java多线程死锁与资源限制操作

    Java多线程死锁与资源限制操作

    这篇文章主要介绍了Java多线程死锁与资源限制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 浅谈为什么阿里巴巴要禁用Executors创建线程池

    浅谈为什么阿里巴巴要禁用Executors创建线程池

    这篇文章主要介绍了浅谈为什么阿里巴巴要禁用Executors创建线程池,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • JAVA中的队列(Queue)详解

    JAVA中的队列(Queue)详解

    这篇文章主要介绍了JAVA中的队列(Queue)详解,队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,需要的朋友可以参考下
    2023-07-07
  • Idea中maven项目实现登录验证码功能

    Idea中maven项目实现登录验证码功能

    这篇文章主要介绍了Idea中maven项目实现登录验证码功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • java大数乘法的简单实现 浮点数乘法运算

    java大数乘法的简单实现 浮点数乘法运算

    大数乘法可以进行任意大小和精度的整数和浮点数的乘法运算, 精确度很高, 可以用作经融等领域的计算,这个是我看了一些资料, 然后自己整理实现的,简单测试了一下
    2014-01-01
  • Spring Task任务调度的实现示例

    Spring Task任务调度的实现示例

    本文主要介绍了Spring Task任务调度的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Java实现英文猜词游戏的示例代码

    Java实现英文猜词游戏的示例代码

    这篇文章主要介绍了如何用Java编写一个英文猜词游戏,可以用来背英语单词。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-02-02
  • springboot Interceptor拦截器excludePathPatterns忽略失效

    springboot Interceptor拦截器excludePathPatterns忽略失效

    这篇文章主要介绍了springboot Interceptor拦截器excludePathPatterns忽略失效的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • MybatisPlus实现简单增删改查功能

    MybatisPlus实现简单增删改查功能

    这篇文章主要介绍了MybatisPlus实现简单增删改查的相关资料,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • java实现的n*n矩阵求值及求逆矩阵算法示例

    java实现的n*n矩阵求值及求逆矩阵算法示例

    这篇文章主要介绍了java实现的n*n矩阵求值及求逆矩阵算法,结合具体实例形式分析了java基于数组的矩阵定义、遍历、运算等相关操作技巧,需要的朋友可以参考下
    2017-09-09

最新评论