You use the cfthread tag and the Sleep function to create and manage ColdFusion threads. You manage a thread by doing the following actions:
- Start the thread running.
- Temporarily suspend the processing of the thread. This action is useful if one thread must wait for another thread to do processing, but both threads must continue processing without joining.
- End a thread. You typically end a running thread if there is an error, or if it is still processing after a long time.
- Have the page or a thread wait until one or more other threads have completed processing before proceeding with its processing, called joining the threads. You typically join threads when one thread requires the results from another thread. For example, if a page uses multiple threads to get several news feeds for display, it joins all the feed threads before it displays the results.
Each thread runs the code inside a cfthread tag body and normally exits when the tag body code completes processing.
Starting a thread
You start a thread by using a cfthread tag with an action attribute value of run. CFML code within the cfthread tag body executes on a separate thread while the page request thread continues processing. Only the page thread can create other threads. A thread that you create with a cfthread tag cannot create a child thread, so you cannot have multiple nested threads.
Optionally, when you start the thread, you can specify a priority level of high, normal (the default), or low to specify the relative amount of time that the processor should devote to the thread. Page-level code always runs at normal priority, so you can give your threads more or less processing time than the page.
For more information on using thread attributes, see The Attributes scope and thread attributes in Using thread data.
Suspending a thread
In some cases, one thread must wait until a second thread completes some operations, but should not wait until the second thread completes all processing, so you cannot just join the threads. For example, one thread might do initialization that multiple threads require, and then it might continue with additional processing. The other threads could suspend themselves until initialization is complete.
The Sleep function and cfthread tag with a sleep action attribute provide two equivalent mechanisms for doing such synchronization. They suspend the thread processing for a specified period of time. A code loop could test a condition variable and sleep for a period before retesting the condition. When the condition is true (or a value is reached, or some other test is valid), the program exits the loop and the thread continues processing.
The following example shows how one thread could use a sleep function to wait for a second thread to perform some actions.
<!--- ThreadA loops to simulate an activity that might take time. --->
Ending a thread
If a thread never completes processing (is hung), it continues to occupy system resources, so it is good practice to have your application check for hung threads and end them. Also consider ending threads that take excessive time to process and might significantly reduce the responsiveness of your application or server.
To end a thread, use the cfthread tag with an action attribute value of terminate, as the following code snippet shows.
<!--- Thread1 sleeps to simulate an activity that might hang. --->
Note: You can also have the ColdFusion Sever Monitor automatically check for and terminate hung threads.
You use the cfthread tag with an action attribute value of join to join two or more threads. You join threads when one thread depends on one or more other threads completing before it can do some processing. For example, a page can start multiple threads to do processing and join them before it processes the thread results. By default, the join action stops the current thread from doing further processing until all the specified threads complete processing.
You can use a timeout attribute to specify the number of milliseconds that the current thread waits for the thread or threads being joined to finish. If any thread does not finish by the specified time, the current thread proceeds without waiting for the remaining thread or threads to complete.
The following code, for example, joins three threads to the current thread (often, the main page thread). The current thread waits up to six seconds for the other threads to complete, and continues processing if one or more threads do not complete by then.
<cfthread action="join" name="t1,t2,t3" timeout="6000"/>
If the timeout attribute value is 0, the default value, the current thread continues waiting until all joining threads finish. In this case, if the current thread is the page thread, the page continues waiting until the threads are joined, even if you specify a page time-out. As a general rule, specify a timeout value to limit hung threads.