Thursday, November 16, 2006

Java: Handling Interrupts

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. A thread can be interrupted by calling the threadObject.interrupt() on the thread object.

threadObject.interrupt();

In order for the interrupt to work, the thread object has to support interruption, i.e. The thread object should check for interruptions periodically, as shown below:

while(!interrupted()) {doWork();}

An interrupt does not force the thread to halt (except when the thread is in sleep or wait mode). As shown in the above piece of code, the thread has to check if it is interrupted and take appropriate action (most likely, cleanup and stop execution). There are two ways in which a thread can check if it is interrupted.

isInterrupted(): This is a non-static method that simply checks whether a thread is interrupted, and returns true or false.

interrupted(): This method (used in the above example) is a static method of the Thread class, which checks if the current thread is interrupted and clears the interrupted state of the thread.

Note: The interrupted state of a thread can be cleaned only by the that thread, no thread can clear the interrupted state of another thread.While interrupting a thread does not affect it's normal execution (unless the thread is programmed to do so), a thread can also be interrupted by an InterruptedException thrown by the sleep or wait methods. This has to be handled in a proper way, since a thrown exception clears the interrupted state of the thread. InterruptedException is best handled in the following way:

The question arises, is when and how should interruptions be handled. Here are some general tips handling interruptions:

If the thread invokes methods that throw InterruptedException frequently, then it is better to catch the interrupted exception and set the interrupted state of the thread as shown above.

If your method blocks, it should respond to interruption, otherwise you must decide what interruption/cancellation means for your method, and make such behavior a part of your method's contract. In general, any method that performs a blocking operation (directly or indirectly), should allow that blocking operation to be cancelled with interrupt and should throw an appropriate exception (as sleep and wait do). If you're using channels, available with the new I/O API introduced in Java 1.4, the blocked thread will get a ClosedByInterruptException exception.

Never hide an interrupt by clearing it explicitly or by catching an InterruptedException and continuing normally as it prevents any thread from being cancellable when executing your code.