Quartz中@DisallowConcurrentExecution注解内部实现逻辑问询
@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:
JobDetail Attribute Sync
When you create aJobDetailfor your annotated Job (either via Quartz's nativeJobBuilderor Spring'sMethodInvokingJobDetailFactoryBean), the framework reads the annotation and sets a boolean propertyconcurrentExectionDisallowed = trueon theJobDetailobject. This is exactly whatMethodInvokingJobDetailFactoryBeandoes—it translates the annotation into a concrete property Quartz's scheduler can act on.Scheduler Trigger Check
When Quartz's mainQuartzSchedulerThreadis ready to trigger a job, it runs two critical checks:- Fetches the
JobDetailtied to the trigger'sJobKey. - Verifies if
jobDetail.isConcurrentExectionDisallowed()returnstrue.
- Fetches the
Active Execution Validation
If concurrent execution is disallowed, the scheduler then checks its internalexecutingJobscollection (managed by theJobStoreimplementation) to see if there's already an active execution of the sameJobKey:- 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
JobKeyto theexecutingJobscollection until the job finishes.
Key Notes to Remember
- The restriction is per
JobKey, not per Job class. If you create two distinctJobDetailinstances (with uniqueJobKeys) for the same annotated Job class, they can still run concurrently. - Spring's
MethodInvokingJobDetailFactoryBeanis just a convenience wrapper—it handles the annotation-to-JobDetailproperty translation so you don't have to do it manually with native Quartz APIs.
内容的提问来源于stack exchange,提问作者Piyush Upadhyay

