An interrupt is an indication to a thread that it should stop what it is doing and do something else. It’s up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate. This is particularly useful in multi-threaded applications where you might want to gracefully stop a thread, handle a long-running task’s termination, or check for some condition periodically.
- Graceful Termination: Interrupts provide a way to terminate threads cleanly, allowing them to perform any necessary cleanup.
- Responsiveness: Threads can periodically check if they have been interrupted and stop their execution, ensuring that the application remains responsive.
- Cooperation: Interrupts enable threads to cooperate with each other, providing a mechanism for safe and coordinated stopping.
<cfscript>
thread action="run" name="myThread" {
try {
while (true) {
// execute tasks...
}
} catch (com.adobe.coldfusion.ThreadInterruptedException ie) {
// catch ThreadInterruptedException, exit while(true) loop, the thread exits
}
}
</cfscript>
When the thread is blocked, and is interrupted it generates a ThreadInterruptedException exception. The exception is captured outside of while(true), so that the while(true) loop is exited! And later we can gracefully clean and close. When the thread is blocked, and is interrupted it generates a ThreadInterruptedException exception. The exception is captured outside of while(true), so that the while(true) loop is exited! And later we can gracefully clean and close.
Usually, we interrupt the thread in running state by calling ThreadInterrupted()
ThreadInterrupted() will determine whether the thread’s interrupt status is true. it will return true if so and clears the flag. At this point, the while loop will exit.
<cfscript>
thread action="run" name="myThread" {
try {
// 1. if the interrupt flag is true, the thread will come out of loop and ready for graceful termination
while (!ThreadInterrupted()) {
// execute tasks...
}
} catch (com.adobe.coldfusion.ThreadInterruptedException ie) {
// 2. Thread must be in blocked state and throws InterruptedException, thread is ready for graceful termination
}
}
</cfscript>
Example of Thread Interruption in Coldfusion
<cfscript>
mythread = "DOWNLOAD_CF"
variables.message="MAIN START at " & now() & "<br>"
chunks = [] // simulating storage
thread action="run" name="#mythread#" {
i = 1;
// simulating chunk storage
try {
variables.message &= "Downloading Started !!" & now() & "<br>";
while( !isThreadInterrupted(mythread) AND i <= 10 ){
Sleep(1000); // Simulate downloading a chunk overnetwork
chunks[i] = "CF PART " & i
variables.message &= "Downloading chunk " & i & " at "& now() &"<br>";
i++
}
if( i == 11 ){
variables.message &= "Download Complete !!";
}else{
variables.message &= "Download Interrupted while running !!";
}
}catch(com.adobe.coldfusion.ThreadInterruptedException ex){
// interruption occurred while in sleep so interrupt status would have been cleared
variables.message &= "Download Interrupted while in sleep !!";variables.message &= "Download Interrupted while in sleep !!";
interruptThread(); // resets interrupt status again to true
}
if( isThreadInterrupted(mythread) ){
// clear all chunks stored -- cleaning
for( j = 1; j < i; j++ ){
chunks[j] = 0;
}
variables.message &= "Download Aborted !!" & "<br>";
}
}
sleep(randRange(5000,15000)) //
interruptThread(mythread); // interrupt from user after random time between 5s to 15s, interrupt will not have any effect after thread has completed
thread action="join"name=mythread {}
writeOutput(variables.message)
writedump(chunks)
</cfscript>
In the example above, we simulate downloading a file in chunks, while handling the possibility of an interruption from the user (or another source). We create a new thread (myThread
) which is responsible for downloading the file in chunks. The simulation involves checking whether the thread has been interrupted during the process and ensuring that it is handled gracefully.
A new thread, myThread
, is started. Inside the thread, a while
loop runs, downloading chunks of the file sequentially. Each chunk of the file is downloaded by performing some work (such as setting values like chunks[i] = "CF PART " & i
). After downloading each chunk, the thread sleeps for a short period before continuing the download. In each iteration of the loop, the thread checks if it has been interrupted. If it has not been interrupted, the thread continues downloading the next chunk. If the user interrupts the thread before all chunks are downloaded, the interruption is handled in two main scenarios:
Scenario 1: Thread is Running
If the thread is executing a line of code (such as chunks[i] = "CF PART " & i
), and the user interrupts the thread:
- The thread’s interrupt status is set to
true
, but the current line of code will continue to execute. - The thread will complete the execution of the current block of code before checking the interrupt status again.
- After finishing the current block of code, the thread checks the condition in the
while
loop (usingisThreadInterrupted
method). - Since the interrupt status was not checked while executing the line, the method
isThreadInterrupted
will returnfalse
, and the thread will exit the loop.
Note: This can result in the interruption being ignored for that specific chunk.
Scenario 2: Thread is Blocked (e.g., Sleeping)
If the thread is blocked on a line (such as Sleep(1000)
), and the user interrupts the thread:
- The interrupt status is set to
true
immediately upon interruption. - The
ThreadInterruptedException
is thrown, which clears the interrupt status. - The exception is caught by a
catch
block, where you can perform any necessary cleanup or additional handling. - Optionally, you can reset the interrupt status to
true
usinginterruptThread
to maintain the interruption flag for future tasks or cleanup.
Note: This allows for a more immediate response to interruption, as the thread is unable to proceed when it is blocked during sleep.
You must be logged in to post a comment.