4

I want some clarification on thread interruption.

What if a thread goes a long time without invoking a method that throws anInterruptedException? Then it must periodically invoke Thread.interrupted, which returns true if an interrupt has been received. For example:

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
    if (Thread.interrupted()) {
        // We've been interrupted: no more crunching.
        return;
    }
}

When I call the method Thread.interrupt() it throws interrupted exception so, why I need to do if (Thread.interrupted()) I will simply do that

try {
    for (int i = 0; i < inputs.length; i++) {
        heavyCrunch(inputs[i]);
        if (Thread.interrupted()) {
            // We've been interrupted: no more crunching.
            return;
        }
    }
} catch (InterruptedException ex) {
        ...
}
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
KarimS
  • 3,812
  • 9
  • 41
  • 64
  • You can use boolean flag to control your thread instead of Thread.interrupted(). It is much safer and cleaner solution – hoaz Mar 12 '14 at 15:27
  • `interrupt()` is an instance method, not a static method, so it would have to be called explicitly on a thread instance. – superEb Mar 12 '14 at 16:01

3 Answers3

4

When you call Thread.interrupt() on another thread, two things happen:

  1. That thread's interrupt flag is set.
  2. If the thread is blocked in a method that throws InterruptedException, that method will throw an exception immediately.

If the thread is busy in some code that does not throw InterruptedException, you won't get any exception. That's why you'd need to check if (Thread.interrupted()), to check the flag.

In your sample code the Java compiler would complain about an invalid catch block because none of the code in the try block throws InterruptedException.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
0

Because Thread.interrupted(), as documented, doesn't throw InterruptedException at all. It returns true or false, and clears the interrupt status that has been set by the call to Thread.interrupt(). Note that Thread.interrupt() doesn't cause an InterruptedException to be thrown either It simply sets the interrupt status.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • But Thread.interrupt() doesn't cause an exception to be thrown. It simply sets the interrupt status on the thread. – JB Nizet Mar 12 '14 at 15:32
  • Under some circumstances e.g. it is waiting/blocked it throws InterruptedException – Martin Wilson Mar 12 '14 at 15:36
  • I know that, but so does the OP, since he asked "What if a thread goes a long time without invoking a method that throws anInterruptedException". – JB Nizet Mar 12 '14 at 15:44
  • I took the question to be: "I have been told/read that if a thread runs for a long time without [a different thread] invoking a method that throws an InterruptedException then it must periodically call Thread.interrupted [to see if it has been interrupted]. However, I don't understand why this is necessary given that Thread.interrupt() throws an InterruptedException" – Martin Wilson Mar 12 '14 at 15:53
0

Calling interrupt on a thread does not directly cause the thread to throw an InterruptedException. All it does is set the interrupt flag for that thread. Methods like sleep, wait, or join can reference that flag on the current thread in order to decide whether to throw an InterruptedException.

Interruption is cooperative, the thread being interrupted decides how it will respond; this way the thread can do whatever cleanup it needs to do and not get shot down partway through.

You should usually use Thread.isInterrupted() because that doesn't change the value of the interrupted flag. Thread.interrupted() resets the flag:

The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).

while Thread.isInterrupted() doesn't:

Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method.

Checking the interrupted flag means your thread can detect whether it's been interrupted without its having to sleep or wait. Neither Thread.isInterrupted() nor Thread.interrupted() throws InterruptedException, the code using it would check the return value.

Also, Thread.interrupt doesn't throw InterruptedException. (And any exception thrown would be in the calling thread, not in the thread being interrupted.) The interrupt method is used to set the interrupt flag on another thread. Having a thread interrupt itself is pointless, the thread could return instead.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276