Thread Usage in Quartz

Threads are extremely important to Quartz because Quartz is designed to support multiple Jobs running simultaneously. To perform this feat, Quartz relies heavily on the thread support built into the Java language and augments it with a few of its own classes and interfaces. You have already seen some of this in the examples in this chapter and the previous one.

When a Quartz Scheduler is first created through one of the factory methods, the factory configures several important resources that the Scheduler will need throughout its lifetime. A few of those important resources have to do with threads.

The Main Processing Thread: QuartzSchedulerThread

When a Quartz application is first launched, the main thread starts the Scheduler. The QuartzScheduler is created and creates an instance of the org.quartz.core.QuartzSchedulerThread class. The QuartzSchedulerThread contains the processing loop for determining when the next job should be triggered. As the name implies, the QuartzSchedulerThread is a Java thread. It runs as a nondaemon thread with a normal priority.

The main processing loop for the QuartzSchedulerThread method is illustrated here:


While the scheduler is running:



Check to see if standby mode has been requested.



If the standby method has been called, wait for the signal to continue.



Ask the JobStore for the next trigger to fire.



If no trigger is ready to fire, wait for a small amount of time check again.


If there's a trigger available, wait for the exact time for it to fire.



When it's time, get the triggerFiredBundle for the trigger.



Create a JobRunShell instance for the job using the Scheduler and triggerFiredBundle.



Tell the ThreadPool to run the JobRunShell when possible.

This logic exists within the run() method of the QuartzSchedulerThread.

The QuartzSchedulerResources

When the factory creates the Scheduler instance, it also passes the Scheduler an instance of an org.quartz.core.QuartzSchedulerResources. The QuartzSchedulerResources contains, among others things, a ThreadPool instance that provides a pool of worker threads that are responsible for executing jobs. In Quartz, a ThreadPool is represented by the org.quartz.spi.ThreadPool interface (because Quartz was invented before JDK 1.5, it needed to create its own ThreadPool classto ensure backward compatibility, Quartz still utilizes its THReadPool instead of Java's) and includes a concrete implementation called org.quartz.simpl.SimpleThreadPool. The SimpleThreadPool has a fixed number of worker threads and doesn't shrink or grow based on load. Figure 4.6 shows the sequence of steps that the framework undergoes during startup as it relates to threads.

Figure 4.6. Several thread-related resources are created at Quartz startup.


What Are Quartz Worker Threads?

Quartz doesn't process your jobs on the main thread. If it did, it would severely reduce the scalability of the application. Instead, Quartz delegates the thread-management responsibilities to a separate component. For the generic Quartz setup, which most users employ, the SimpleThreadPool class handles thread management. The SimpleThreadPool creates a number of WorkerThread instances that are responsible for processing a job on a separate thread. The WorkerThread is an inner class defined within the SimpleThreadPool class and is essentially a thread. The number of WorkerThreads that are created and the priority for these threads are specified by the configuration settings in the file or are passed into the factory.

When the QuartzSchedulerThread asks the ThreadPool to run a JobRunShell instance, the ThreadPool checks to see if a worker thread is available. If all the configured worker threads are busy, the ThreadPool waits until one becomes available. When a worker thread is available and a JobRunShell is waiting to be executed, the worker thread calls the run() method on the JobRunShell class.

Configuring Alternative THReadPools

The Quartz framework enables you to change the ThreadPool implementation that is used. The alternative must implement the org.quartz.spi.ThreadPool interface, but the framework supports this through the use of configuration files. For example, you can use more advanced ThreadPool implementations that change the number of threads based on demand or even get the worker threads from an application server. For most users, the default implementation will suffice.


The JobRunShell run() Method

Although WorkerThreads are indeed Java threads, the JobRunShell class implements Runnable as well. That means that it can act as a thread and contains a run() method. As discussed earlier in the chapter, the purpose of the JobRunShell is to call the execute() method on a job. It does this and also notifies the job and trigger listeners, and it finishes by updating trigger information about the execution.

Scheduling in the Enterprise

Getting Started with Quartz

Hello, Quartz

Scheduling Jobs

Cron Triggers and More

JobStores and Persistence

Implementing Quartz Listeners

Using Quartz Plug-Ins

Using Quartz Remotely

Using Quartz with J2EE

Clustering Quartz

Quartz Cookbook

Quartz and Web Applications

Using Quartz with Workflow

Appendix A. Quartz Configuration Reference

Quartz Job Scheduling Framework(c) Building Open Source Enterprise Applications
Quartz Job Scheduling Framework: Building Open Source Enterprise Applications
ISBN: 0131886703
EAN: 2147483647
Year: N/A
Pages: 148 © 2008-2020.
If you may any questions please contact us: