Quartz原理解析

Quartz原理解析

最近项目中好多地方都须要用到定时器,一开始用的是netty的hashWheel,后来发现删除任务的时候不是很好删除,因而就放弃了,而后选择了Quartz。html

  • hashWheel定时器和Quartz的区别:

1)Quartz将定时任务分为任务和触发器,而hashWheel只有任务的概念spring

2)Quartz经过一个TreeSet对全部的触发器进行管理,而hashWheel经过一个hash轮来对全部的任务进行管理数据库

3)Quartzl可以很是方便的删除定时任务,而netty的hashWheel暂时没有删除任务的接口(除非本身实现一个hashWheel定时器)app

4)Quartz有一个专门的调度线程对任务进行管理,任务执行有另外专门的线程池,而hashWheel用一个线程实现对任务的管理和任务的执行。函数

5)Quartz可以经过序列化,将定时任务保存在数据库,而hashWheel不能post

总的来讲,Quartz的功能相对强大,而hashWheel相对要轻量级一点。spa

 

  • Quartz定时器原理:

接下来就讲讲Quartz的原理。线程

1)首先任务调度器调度的时序大体以下所示:3d

在这里将几个重要的类调用的过程以序列图的形式展示出来,上半部分展示的是启动过程,下半部分展示的是任务调度的过程。netty

步骤1.用户首先须要生成一个调度器工厂SchedulerFactory,能够用下面的方式实现本身的定制化:

1 Properties properties=new Properties();    properties.put("org.quartz.threadPool.class","org.quartz.simpl.SimpleThreadPool");
2 properties.put("org.quartz.threadPool.threadCount","10");
3 SchedulerFactory sf=new StdSchedulerFactory(properties);

步骤2.而后经过getScheduler()方法从调度器工厂里获得调度器实例,首先查找有没有这样的调度器,没有的话,就生成一个,有的话直接返回。因此获得的通常是单例,即默认的调度器。

步骤3.Scheduler有一个QuartzSchedulerThread(Thread的子类)属性,在scheduler实例化的时候,实例化了一个对象,并用ThreadExecutor启动该线程对象。该线程就是调度线程,主要任务就是不停的从JobStore中获取即将被触发的触发器(默认30s调度一次)。在这个时候调度线程虽然启动,可是处于pause状态。

步骤4.接下来是任务调度的部分:

1 Scheduler scheduler=sf.getScheduler();
2 scheduler.addJobListener(new TaskListener());
3 scheduler.scheduleJob(jobDetail, simpleTrigger);
4 scheduler.start();

client经过scheduleJob()方法将任务和触发器存储在JobStore中,经过start()方法将QuartzSchedulerThread的pause状态设为false,通知调度线程执行任务,此后调度线程不停的从JobStore中去取即将触发的任务。

 

2)任务执行的时序以下所示:

上半部分展示的是任务执行以前准备工做的时序,下半部分展示的是任务执行的时序。

步骤1.调度线程首先去线程池中获取可用的线程,若是没有的话,就阻塞。

步骤2.从JobStore(从存储介质中获取触发器,存储介质能够是内存也能够是数据库)获取(接下来30s内的)触发器,而后等待该触发器触发。

步骤3.调度线程建立一个JobRunShell(就是一个Runnable),而后从线程池中调用线程执行该任务。

接下来就是任务执行的时序:

步骤4.获取trigger、JobDetail以及生成Job实例,而后执行job的execute接口函数。

 

3)持久化的任务的执行时序以下:

 

以上就是Quartz的基本工做流程。

 

我在使用的时候遇到的一些问题:

1.Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象?

这个问题网上已经有解决方法,可是按照它的步骤执行以后仍是不行,后来通过尝试发现,在实现接口ApplicationContextAware的时候,须要将private ApplicationContext applicationContext;改为静态的private static ApplicationContext applicationContext,

以后这个问题就获得完美解决了。

相关文章
相关标签/搜索