Wednesday, August 11, 2010

Quartz CronTrigger Scheduling Policy - Fixed-Rate or Fixed-Delay?

As you know the Java Timer class allows you to schedule task either as Fixed-Rate or Fixed-Delay.

In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate). 

Quartz supports Unix/Linux-like cron scheduling with its CronTrigger class which has a fixed-rate like execution policy.
For example if you configured your job to run every 5 seconds in a thread pool with more than 1 worker thread, the job will be kicked off every five 5 seconds.
If the previous job execution has not be done yet, the new job execution will pick up an available worker thread in the thread pool. This is different from Java's Timer which only has one single worker thread.

Quartz doesn't support Fixed-delay as of version 1.6. Actually you can find the details by digging into its source code.
The key classes and interfaces are its QuartzScdedulerThread, JobStore and CronTirgger.
In method run() of QuartzScdedulerThrea, you can find it calls triggerFired() before calling runInThread() to actually run the job.
triggerFired() will eventually lead to a call to triggered() in CronTrigger where nextFireTime is calculated.
So you know no matter how long your job run in runInThread(), the next execution time is always correctly calculated from its last execution time by method triggerFired().

No comments:

Post a Comment