You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quartz中@DisallowConcurrentExecution注解内部实现逻辑问询

Understanding Quartz's @DisallowConcurrentExecution Internal Logic

Great question! It's totally normal to overlook the enforcement logic since the annotation itself is just a marker with no code inside. Let's walk through exactly how Quartz makes sure your jobs don't run concurrently when you use this annotation.

First: The Annotation is Just a Marker

As you saw, the @DisallowConcurrentExecution definition is minimal—it's purely a flag for Quartz's core scheduler:

@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface DisallowConcurrentExecution { }

No logic lives here; it just signals to Quartz how to handle instances of the annotated Job class.

How Quartz Enforces the Concurrent Execution Block

The actual enforcement happens in Quartz's core scheduling pipeline, broken down into these key steps:

  1. JobDetail Attribute Sync
    When you create a JobDetail for your annotated Job (either via Quartz's native JobBuilder or Spring's MethodInvokingJobDetailFactoryBean), the framework reads the annotation and sets a boolean property concurrentExectionDisallowed = true on the JobDetail object. This is exactly what MethodInvokingJobDetailFactoryBean does—it translates the annotation into a concrete property Quartz's scheduler can act on.

  2. Scheduler Trigger Check
    When Quartz's main QuartzSchedulerThread is ready to trigger a job, it runs two critical checks:

    • Fetches the JobDetail tied to the trigger's JobKey.
    • Verifies if jobDetail.isConcurrentExectionDisallowed() returns true.
  3. Active Execution Validation
    If concurrent execution is disallowed, the scheduler then checks its internal executingJobs collection (managed by the JobStore implementation) to see if there's already an active execution of the same JobKey:

    • If an active execution exists, the scheduler skips immediate triggering. Instead, it requeues the trigger for a later time (aligned with the trigger's configuration).
    • If no active execution is found, the scheduler assigns a thread from the thread pool to run the job, and adds the JobKey to the executingJobs collection until the job finishes.

Key Notes to Remember

  • The restriction is per JobKey, not per Job class. If you create two distinct JobDetail instances (with unique JobKeys) for the same annotated Job class, they can still run concurrently.
  • Spring's MethodInvokingJobDetailFactoryBean is just a convenience wrapper—it handles the annotation-to-JobDetail property translation so you don't have to do it manually with native Quartz APIs.

内容的提问来源于stack exchange,提问作者Piyush Upadhyay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:40:54