`
wxyfighting
  • 浏览: 202745 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Quartz源码分析(一)------ 以线程等待的方式实现按时间调度

 
阅读更多

Quartz是运用最广的任务调度框架,它最核心的组成部分是Scheduler、Trigger、JobDetail,然后给Scheduler配置个线程QuartzSchedulerThread,此线程在Scheduler初始化时启动,等待Scheduler start,然后从JobStore里拿到最近要触发的Trigger,以线程等待的方式等到trigger触发时间点,之后就是执行trigger所关联的JobDetail,最后清扫战场。Scheduler初始化、start和trigger执行的时序图如下所示:

其中,最核心的地方是QuartzSchedulerThread运行机制。下面解析一下它的run方法:

  1. publicvoidrun(){
  2. booleanlastAcquireFailed=false;
  3. while(!halted){
  4. try{
  5. //checkifwe'resupposedtopause...
  6. synchronized(pauseLock){
  7. while(paused&&!halted){
  8. try{
  9. //waituntiltogglePause(false)iscalled...
  10. pauseLock.wait(100L);
  11. }catch(InterruptedExceptionignore){
  12. }
  13. }
  14. if(halted){
  15. break;
  16. }
  17. }
  18. ......
  19. }
  20. }

以上是run的最开头的一段,不难看出这是在等待scheduler的start,实际上Quartz就是通过线程的wait或sleep来实现时间调度。继续看代码:

  1. Triggertrigger=null;
  2. longnow=System.currentTimeMillis();
  3. signaled=false;
  4. try{
  5. trigger=qsRsrcs.getJobStore().acquireNextTrigger(
  6. ctxt,now+idleWaitTime);
  7. lastAcquireFailed=false;
  8. }catch(JobPersistenceExceptionjpe){
  9. if(!lastAcquireFailed){
  10. qs.notifySchedulerListenersError(
  11. "Anerroroccuredwhilescanningforthenexttriggertofire.",
  12. jpe);
  13. }
  14. lastAcquireFailed=true;
  15. }catch(RuntimeExceptione){
  16. if(!lastAcquireFailed){
  17. getLog().error("quartzSchedulerThreadLoop:RuntimeException"
  18. +e.getMessage(),e);
  19. }
  20. lastAcquireFailed=true;
  21. }

这段代码是从jobStore里拿到下一个要执行的trigger,一般情况下jobStore使用的是RAMJobStore,即trigger等相关信息存放在内存里,如果需要把任务持久化就得使用可持久化JobStore。继续看代码:

  1. now=System.currentTimeMillis();
  2. longtriggerTime=trigger.getNextFireTime().getTime();
  3. longtimeUntilTrigger=triggerTime-now;
  4. longspinInterval=10;
  5. intnumPauses=(int)(timeUntilTrigger/spinInterval);
  6. while(numPauses>=0&&!signaled){
  7. try{
  8. Thread.sleep(spinInterval);
  9. }catch(InterruptedExceptionignore){
  10. }
  11. now=System.currentTimeMillis();
  12. timeUntilTrigger=triggerTime-now;
  13. numPauses=(int)(timeUntilTrigger/spinInterval);
  14. }
  15. if(signaled){
  16. try{
  17. qsRsrcs.getJobStore().releaseAcquiredTrigger(
  18. ctxt,trigger);
  19. }catch(JobPersistenceExceptionjpe){
  20. qs.notifySchedulerListenersError(
  21. "Anerroroccuredwhilereleasingtrigger'"
  22. +trigger.getFullName()+"'",
  23. jpe);
  24. //dbconnectionmusthavefailed...keep
  25. //retryinguntilit'sup...
  26. releaseTriggerRetryLoop(trigger);
  27. }catch(RuntimeExceptione){
  28. getLog().error(
  29. "releaseTriggerRetryLoop:RuntimeException"
  30. +e.getMessage(),e);
  31. //dbconnectionmusthavefailed...keep
  32. //retryinguntilit'sup...
  33. releaseTriggerRetryLoop(trigger);
  34. }
  35. signaled=false;
  36. continue;
  37. }

此段代码是计算下一个trigger的执行时间和现在系统时间的差,然后通过循环线程sleep的方式暂停住此线程,一直等到trigger的执行时间点。继续看代码:

  1. importorg.quartz.core.JobRunShell;
  2. JobRunShellshell=null;
  3. try{
  4. shell=qsRsrcs.getJobRunShellFactory().borrowJobRunShell();
  5. shell.initialize(qs,bndle);
  6. }catch(SchedulerExceptionse){
  7. try{
  8. qsRsrcs.getJobStore().triggeredJobComplete(ctxt,
  9. trigger,bndle.getJobDetail(),Trigger.INSTRUCTION_SET_ALL_JOB_TRIGGERS_ERROR);
  10. }catch(SchedulerExceptionse2){
  11. qs.notifySchedulerListenersError(
  12. "Anerroroccuredwhileplacingjob'striggersinerrorstate'"
  13. +trigger.getFullName()+"'",se2);
  14. //dbconnectionmusthavefailed...keepretrying
  15. //untilit'sup...
  16. errorTriggerRetryLoop(bndle);
  17. }
  18. continue;
  19. }
  20. if(qsRsrcs.getThreadPool().runInThread(shell)==false){
  21. try{
  22. getLog().error("ThreadPool.runInThread()returnfalse!");
  23. qsRsrcs.getJobStore().triggeredJobComplete(ctxt,
  24. trigger,bndle.getJobDetail(),Trigger.INSTRUCTION_SET_ALL_JOB_TRIGGERS_ERROR);
  25. }catch(SchedulerExceptionse2){
  26. qs.notifySchedulerListenersError(
  27. "Anerroroccuredwhileplacingjob'striggersinerrorstate'"
  28. +trigger.getFullName()+"'",se2);
  29. //dbconnectionmusthavefailed...keepretrying
  30. //untilit'sup...
  31. releaseTriggerRetryLoop(trigger);
  32. }
  33. }

此段代码就是包装trigger,然后通过以JobRunShell为载体,在threadpool里执行trigger所关联的jobDetail。

之后的代码就是清扫战场,就不在累述。

分享到:
评论

相关推荐

    quartz源码解析(一)

    这篇博客“quartz源码解析(一)”可能是博主对Quartz核心原理、设计模式以及其实现细节的一个初步探讨。 Quartz的源码分析可以从以下几个方面入手: 1. **设计模式**: - **工厂模式**:Quartz中Job和Trigger的...

    quartz-1.6.4.源码

    Quartz 是一个开源的作业调度框架,用于在 Java 应用程序中实现复杂的时间调度任务。版本 1.6.4 提供了稳定的调度服务,适用于各种企业级应用。源码分析可以帮助我们深入理解其内部机制,从而更好地利用或定制这个...

    quartz-1.4.5以及源码

    Quartz是Java平台上的一款强大的作业调度框架,常用于在企业级应用中实现任务调度。版本1.4.5是该框架的一个稳定版本,虽然现在已经有更新的版本,但对于某些老系统来说,它仍然具有重要的维护价值。这个压缩包包含...

    quartz-2.1.7 官方jar包源码

    源码分析对于理解Quartz的工作原理至关重要。在Quartz-2.1.7源码中,你可以看到如下关键组件: 1. `org.quartz.core` 包:这是Quartz的核心模块,包含Scheduler、JobStore和ThreadPool的主要实现。SchedulerImpl是...

    quartz1.6.0源码

    源码分析有助于深入理解其内部工作原理,从而更好地利用它来满足各种复杂的定时需求。Quartz 1.6.0源码包提供了一个宝贵的资源,帮助开发者探索其设计模式、线程管理以及任务调度的机制。 1. **Quartz核心概念** -...

    quartz-3.0.3.1_quartes_源码.zip

    Quartz 是一个开源的作业调度框架,用于在 Java 应用程序中实现复杂的时间调度任务。这个压缩包 "quartz-3.0.3.1_quartes_源码.zip" 包含了 Quartz 框架的源代码,版本为 3.0.3.1,对于学习和理解 Quartz 的工作原理...

    quartz-2.2 需要的jar以及src源代码

    Quartz是Java领域一个广泛应用的开源任务调度框架,它的核心功能是允许开发者安排任务在特定时间执行,或者按一定间隔重复执行。这个压缩包“quartz-2.2.3”包含了Quartz库的jar文件以及源代码,这对于开发者理解和...

    quartz-master.zip

    Quartz是一款开源的作业调度框架,它允许程序创建和管理定时任务。在Java开发中,Quartz被广泛用于...此外,对于希望参与开源项目或者对任务调度有深入需求的开发者,理解并可能贡献Quartz源码将是一次宝贵的学习经历。

    任务调度开源框架Quartz

    Quartz是一款广泛应用于Java环境中的开源任务调度框架,它提供了高度可配置的作业调度系统,使得开发者能够轻松地在应用程序中实现定时任务的管理。Quartz的核心特性包括但不限于以下几点: 1. **灵活的调度**:...

    Quartz集群配置和示例源码

    Quartz是一款开源的作业调度框架,它允许开发者在Java应用程序中定义定时任务,实现复杂的调度逻辑。集群配置是Quartz为了提高系统可用性和任务处理能力而设计的一种模式,它可以确保在一个集群环境中,即使某个节点...

    quartz-2.2.3.jar完整包

    Quartz是Java领域一款广泛应用的开源任务调度框架,它的核心功能是允许开发者安排任务在特定的时间点执行。在"quartz-2.2.3.jar"这个完整包中,包含了Quartz库的所有必要组件,以及示例源码、开发文档和其他相关联的...

    作业调度Quartz.net源代码

    通过阅读源码,开发者可以了解到Quartz.NET的实现细节,例如作业调度算法、线程管理策略以及如何与不同存储机制交互。 总之,这个资源对于想要深入研究和使用Quartz.NET的人来说非常有价值。通过学习源码和DEMO,你...

    Quartz.NET 官方源码

    此外,Quartz.NET还支持集群模式,允许多个调度器实例共享同一份作业和触发器的状态,以实现高可用性和故障转移。 Quartz.NET的持久化机制也很关键,它允许在应用程序重启后恢复之前的调度状态。默认情况下,Quartz...

    xxl job源码分析

    xxl-job是一个轻量级的任务调度平台,具备开源特性,其源码分析对于工程开发人员具有一定的参考价值。接下来,我们将详细介绍xxl-job的核心概念、架构特点以及源码分析过程中的关键知识点。 首先,xxl-job项目的...

    FreePay_Quartz_aug_2008-源码.rar

    开发者可以设置触发器类型,如SimpleTrigger(简单触发器)或CronTrigger(基于Cron表达式的时间触发器),以实现不同的调度策略。 4. **持久化机制**:Quartz支持数据库持久化,这意味着即使服务器重启,调度信息...

    quartz-master.zip 2.3.2源码

    Quartz是一款开源的作业调度框架,它允许开发者在Java应用程序中安排任务的执行。Quartz 2.3.2是该框架的一...对于希望深入学习任务调度和Java后台服务开发的开发者来说,Quartz 2.3.2的源码分析是一份宝贵的学习资源。

    Quartz 定时任务web使用

    Quartz 是一个开源的作业调度框架,常用于Java应用程序中实现定时任务的管理。它提供了丰富的API和功能,使得开发者可以灵活地定义和控制任务的执行。本篇将重点介绍如何在Web环境中集成并使用Quartz,以及相关的...

    任务调度源码.net

    此外,源码分析可以帮助你理解Quartz.NET如何实现线程安全、任务调度算法、触发器的解析与管理,以及如何优雅地处理任务异常和调度冲突。通过阅读源码,你还可以学习到多线程编程、事件驱动编程和设计模式的应用。 ...

    Quartz任务调度

    Quartz任务调度是一款开源的Java定时任务框架,它允许开发者精确地控制任务的执行时间,提供了丰富的调度功能,被广泛应用于各种系统中的定时任务管理。Quartz的核心是基于作业(Job)和触发器(Trigger)的概念,...

    quartz定时器源码jar包下载

    6. **并发与线程管理**:Quartz在多线程环境下运行,分析`org.quartz.core.QuartzSchedulerThread`,了解其内部调度机制。 7. **插件系统**:Quartz有一个强大的插件系统,如`org.quartz.plugins.history....

Global site tag (gtag.js) - Google Analytics