quartz学习二--监听、排除日期、线程

原创 2016年06月01日 15:24:48
一、Listener
    1、基本概念
       (1)、分类
            JobListener

        TriggerListener

        SchedulerListener

       (2)、作用
            可以扩展框架并定制来做特定的事情。跟Spring,Hibernate,Servlet监听器类似.

       (3)、全局和非全局监听器
            a、JobListener 和 TriggerListener 可被注册为全局或非全局监听器。
        
            b、区别
           全局监听器能接收到所有的 Job/Trigger 的事件通知。
           全局监听器是主动意识的,它们为了执行它们的任务而热切的去寻找每一个可能的事件

           非全局监听器只能接收到那些在其上已注册了监听器的 Job 或 Triiger 的事件。
           非全局监听器一般是被动意识的,它们在所关注的 Trigger 激发之前或是 Job 执行之前什么事也不做。

    2、JobListener
       (1)、源码
            public interface JobListener {  
               //命名jobListener 只对非全局监听器有效  
               public String getName();  
      
               //Scheduler 在 JobDetail 将要被执行时调用这个方法。  
               public void jobToBeExecuted(JobExecutionContext context);  
      
               //Scheduler 在 JobDetail 即将被执行,但又被否决时调用这个方法。  
               public void jobExecutionVetoed(JobExecutionContext context);  
      
               //Scheduler 在 JobDetail 被执行之后调用这个方法。  
               public void jobWasExecuted(JobExecutionContext context,JobExecutionException jobException);  
            }

       (2)、使用
            JobListener jobListener = new SimpleJobListener("SimpleJobListener");         
            
            全局监听: scheduler.addGlobalJobListener(jobListener);
           
            局部监听: scheduler.addJobListener(jobListener);//依次完成,顺序不能颠倒
              jobDetail.addJobListener(jobListener.getName());
              scheduler.addjob(jobDetail,true);  

    3、TriggerListener
       (1)、源码
            public interface TriggerListener {  
               //命名triggerListener 只对非全局监听器有效  
               public String getName();  
 
               //当与监听器相关联的 Trigger 被触发,Job 上的 execute() 方法将要被执行时,调用这个方法。  
               //在全局TriggerListener 情况下,这个方法为所有 Trigger 被调用。(不要做耗时操作)  
               public void triggerFired(Trigger trigger, JobExecutionContext context);  
 
               //在 Trigger 触发后,Job 将要被执行时由调用这个方法。  
               //TriggerListener给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。  
               public boolean vetoJobExecution(Trigger trigger, JobExecutidonContext context);  
 
               // Scheduler 调用这个方法是在 Trigger 错过触发时。  
               // JavaDoc 指出:你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小  
               public void triggerMisfired(Trigger trigger);  
 
               //Trigger 被触发并且完成了Job的执行时调用这个方法。  
               public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode);  
            }
            
       (2)、使用
            TriggerListener triggerListener = new SimpleTriggerListener();         
           
            全局监听: scheduler.addGlobalTriggerListener(triggerListener);
            
            局部监听: scheduler.addTriggerListener(triggerListener);
              trigger.addTriggerListener(triggerListener.getName());

    4、SchedulerListener
       (1)、源码
            public interface SchedulerListener {  
               //有新的JobDetail部署调用这个方法。  
               public void jobScheduled(Trigger trigger);  
      
               //卸载时调用这个方法。  
               public void jobUnscheduled(String triggerName, String triggerGroup);  
      
               //当一个Trigger到达再也不会触发时调用这个方法。  
               public void triggerFinalized(Trigger trigger);  
      
               //Scheduler 调用这个方法是发生在一个Trigger或多个Trigger被暂停时。假如是多个Trigger的话,triggerName 参数将为null。  
               public void triggersPaused(String triggerName, String triggerGroup);  
      
               //Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是多个Trigger的话,triggerName 参数将为 null。  
               public void triggersResumed(String triggerName,String triggerGroup);  
      
               //当一个或一组 JobDetail 暂停时调用这个方法。  
               public void jobsPaused(String jobName, String jobGroup);  
      
               //当一个或一组 Job 从暂停上恢复时调用这个方法。假如是多个Job,jobName参数将为 null。  
               public void jobsResumed(String jobName, String jobGroup);  
      
               // 在Scheduler 的正常运行期间产生一个严重错误时调用这个方法。错误的类型会各式的,但是下面列举了一些错误例子:  
               // 可以使用 SchedulerException 的 getErrorCode() 或者 getUnderlyingException() 方法或获取到特定错误的更详尽的信息  
               public void schedulerError(String msg, SchedulerException cause);  
      
               //Scheduler 调用这个方法用来通知 SchedulerListener Scheduler 将要被关闭。  
               public void schedulerShutdown();  
            }  
   
       (2)、使用
            scheduler.addSchedulerListener(schedulerListener);

二、org.quartz.Calendar
    1、定义
       专门用于屏闭一个时间区间,使 Trigger 在这个区间中不被触发。 是一些日历特定时间点的集合

    2、作用
       一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。

    3、原生Calendar实现
       org.quartz.impl.calendar.BaseCalender                 --->        为高级的 Calender 实现了基本的功能,实现了 org.quartz.Calender 接口
       org.quartz.impl.calendar.WeeklyCalendar                --->         排除星期中的一天或多天,例如,可用于排除周末
       org.quartz.impl.calendar.MonthlyCalendar                --->        排除月份中的数天,例如,可用于排除每月的最后一天
       org.quartz.impl.calendar.AnnualCalendar                --->        排除年中一天或多天
       org.quartz.impl.calendar.HolidayCalendar                --->        特别的用于从 Trigger 中排除节假日
       
    4、使用
       AnnualCalendar cal = new AnnualCalendar();
       ...
       scheduler.addCalendar("crmHolidays", cal, true, true);
       trigger.setCalendarName("crmHolidays");

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

    2、SimpleThreadPool
       一个Quartz默认实现的简单线程池,它足够健壮,能够应对大部分常用场景

    3、ThreadExecutor / DefaultThreadExecutor
       内部线程操作对象

    4、org.quartz.spi.ThreadPool 接口
       自定义 quartz 线程池

四、quartz与线程
    1、主处理线程(QuartzSchedulerThread)
       (1)、原理
            启动Scheduler时。QuartzScheduler被创建并创建一个org.quartz.core.QuartzSchedulerThread 类的实例。

            QuartzSchedulerThread 包含有决定何时下一个Job将被触发的处理循环。
        
        QuartzSchedulerThread 是一个 Java 线程。它作为一个非守护线程运行在正常优先级下。
    
       (2)、主处理轮循步骤
            a、当 Scheduler 正在运行时:
           检查是否有转换为 standby 模式的请求。

            b、假如 standby 方法被调用,等待继续的信号
           询问 JobStore 下次要被触发的 Trigger.

            c、如果没有 Trigger 待触发,等候一小段时间后再次检查

            d、假如有一个可用的 Trigger,等待触发它的确切时间的到来
           时间到了,为 Trigger 获取到 triggerFiredBundle.

           使用Scheduler和triggerFiredBundle 为 Job 创建一个JobRunShell实例

           在ThreadPool 申请一个线程运行 JobRunShell 实例.

    2、工作者线程
       (1)、原理
            Quartz 不会在主线程(QuartzSchedulerThread)中处理用户的Job。
        
        Quartz 把线程管理的职责委托给ThreadPool。

       (2)、org.quartz.simpl.SimpleThreadPool。
        SimpleThreadPool 创建了一定数量的 WorkerThread 实例来使得Job能够在线程中进行处理。

        WorkerThread 是定义在 SimpleThreadPool 类中的内部类,它实质上就是一个线程。

        要创建 WorkerThread 的数量以及配置他们的优先级是在文件quartz.properties中并传入工厂。

       (3)、流程
        主线程(QuartzSchedulerThread)请求ThreadPool去运行 JobRunShell 实例,
        ThreadPool 就检查看是否有一个可用的工作者线程。
        
        假如所以已配置的工作者线程都是忙的,ThreadPool 就等待直到有一个变为可用。

        当一个工作者线程是可用的, 并且有一个JobRunShell 等待执行,工作者线程就会调用 JobRunShell 类的 run() 方法。






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

QuartZ的线程锁

1. 自定义QuartZ的并发锁 using System; using System.Threading; using log4net; using Quartz; namespace HK.G...
  • heoo442
  • heoo442
  • 2015年09月08日 22:06
  • 966

quartz执行卡死--强制中断线程

在quartz中经常会碰到由于网络问题或者一些其他不稳定因素导致的线程卡死问题,这往往会导致数据处理的延时。而有时候一时无法定位到卡死的原因,为了降低系统风险,我们就会希望有一个超时机制,当执行超时时...

window下监听程序是线程而linux下则是进程

在Linux下,监听程序就是tnslsnr.exe,根据监听名来读取listener.ora文件里的相关监听配置后,先创建出它的一个复制进程,并用这些相关监听配置初始化该进程)。用命令形式表达就是“t...
  • haiross
  • haiross
  • 2013年11月21日 10:55
  • 1115

Event System事件系统【SWING监听事件的线程问题】

Event System事件系统 一个事件要求特定的动作被执行,它被作为消息由外界或系统自身发送给GUI系统。这些事件包括来自计算机设备如鼠标键盘和网络端口的I/O中断,以及GUI系统的逻辑事件触发...

C#子线程中进行UDP报文的监听

这两天,在改一个程序,程序的主要功能是: 1. 点击ScanButton按钮,触发事件,发送广播报文 2. 开启一个子线程,进行UDP报文监听,如果接收到符合格式的报文,则做相应的处理 3. 1...

2015-11-12 android对变量监听(一)使用子线程定时监察

事情的起因是这样的:   人物:我,一个学习JAVA总共46天的小菜鸟。 事件:在编程做一款android五子棋游戏。 需求:需要在人或机某一方获得胜利后,动态加载一个带按钮和文本的Fragment,...

MFC串口调试助手线程监听事件小解

这里以线程监听串口数据,实现串口数据的自动接收为例进行说明: 首先,线程监听需要一个线程函数:(DWORD WINAPI) UINT  CSerialDAWDlg::ThreadFunc(LPVO...

通过广播接收者(BroadcastReceiver)或守护线程启动服务,录音机监听电话

一:通过广播接收者启动服务 例如,系统收到开机的广播后启动服务 public class B...

OkHttp 使用 get post UI线程回调 上传 下载 进度监听 更好地封装

前几天自己写了一个OkHttp的封装 因为自己在项目中有用到,包括post请求,自定义接口UI更新,上传下载进度显示 用起来也还行,该有的都有,但是今天看了一下网上一些关于OKHttp的资料,说来也是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:quartz学习二--监听、排除日期、线程
举报原因:
原因补充:

(最多只允许输入30个字)