3

I have a thread in Java which calls

t.interrupt();

making t (a different thread) be interrupted. I want the "t" thread to then catch an InterruptedException but Eclipse won't let me put an InterruptedException in saying it's not thrown in the try body. How can I get the InterruptedException to be called? Am I using t.interrupt() wrong?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
user760220
  • 1,207
  • 2
  • 13
  • 12
  • could you please paste in the bit with the catch? – radai Jul 24 '13 at 16:52
  • possible duplicate of [What does java.lang.Thread.interrupt() do?](http://stackoverflow.com/questions/3590000/what-does-java-lang-thread-interrupt-do) – Gray Jul 24 '13 at 18:17
  • Also related to: http://stackoverflow.com/questions/2289885/when-an-thread-interrupt-is-called-on-some-thread-what-happens?lq=1 – Gray Jul 24 '13 at 18:17

4 Answers4

12

I want the "t" thread to then catch an InterruptedException but Eclipse won't let me put an InterruptedException in saying it's not thrown in the try body. How can I get the InterruptedException to be called? Am I using t.interrupt() wrong?

It is important to realize that t.interrupt() only sets the interrupted bit in a thread -- it doesn't actually interrupt the thread's processing per se. A thread can be interrupted at any time safely.

To quote from the Thread.interrupt() javadocs:

  • If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

  • If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a java.nio.channels.ClosedByInterruptException.

  • If this thread is blocked in a java.nio.channels.Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

  • If none of the previous conditions hold then this thread's interrupt status will be set.

It is important to add that if the thread's interrupt bit has been set and then wait() (and others) is called, then the wait() will throw InterruptedException immediately.

So you can't catch InterruptedExeption everywhere since only certain methods throw it. If you want to see if a thread has been interrupted (again has the interrupt bit set) then the right thing to do is to test for it directly with the Thread.getCurrentThread().isInterrupted(). Typically we do something like the following:

while (!Thread.getCurrentThread().isInterrupted()) {
     // process stuff
     ...
     try {
         // here's an example of a method that throws InterruptedException
         Thread.sleep(100);
     } catch (InterruptedException e) {
         // throwing InterruptedException actually clears the interrupt bit
         // so it is a good pattern to re-interrupt the thread immediately
         Thread.currentThread().interrupt();
         // now we decide what to do since we are interrupted
         // you most likely shouldn't just continue processing
         break;
     }
}

There are a number of good questions and answers on this topic:

Gray
  • 115,027
  • 24
  • 293
  • 354
  • 1
    Thanks very much, For me it's not logic at all to be forced to re-interrupt several time the same thread because it has been caught somewhere. But thanks for your answer, because before read it I was really wondering what was going on ! – VelocityPulse Mar 18 '20 at 11:07
7

While the other answers are correct, a fuller explanation is appropriate.

A thread can be safely interrupted (in the general sense of the word) only at specific points in its execution. In particular, it can be interrupted safely when it has issued a wait() call, or has invoked a service that can issue wait(). This is why InterruptedException is a checked exception and not a runtime (unchecked) exception. Allowing a thread to be arbitrarily interrupted at any point would make execution non-deterministic (at least that's the way the JVM was specified). There is a Thread#stop() method which is strongly deprecated because it causes more problems than it solves. From the Javadoc

This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

If you need to interrupt a running thread, then you must periodically poll the interrupted status with Thread.interrupted() or .isInterrupted() or poll a shared variable, and take appropriate action yourself.

Note: The term "interrupted" above (except as part of a method name) is intended in the general sense, not the specific meaning of calling Thread#interrupt().

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • 1
    The thread can be "safely" interrupted at any time. The next `wait()` or others will then throw. You can also check for `Thread.currentThread().isInterrupted()`. – Gray Jul 24 '13 at 18:22
  • Either your thread is in a processing loop or it's waiting. If it's in a processing loop, check the flag once per iteration and take action if an interrupt has been requested. – Jim Garrison Jul 24 '13 at 21:42
  • @Gray I guess the confusion comes from overloading the meaning of the word "interrupted". I was using it in the general sense, not the specific meaning of calling `Thread.interrupt()`, in which case my answer is completely valid. – Jim Garrison Jul 24 '13 at 21:43
  • I still don't get it @JimGarrison. In the general sense, why can a thread only be "safely" interrupted at specific points in its execution? Are you maybe trying to say that a thread will throw an `InterruptedException` at certain points? – Gray Jul 24 '13 at 21:46
  • @Gray Read the deprecation warning and associated link from the Javadoc (reproduced in my answer). – Jim Garrison Jul 24 '13 at 21:48
  • I know about those deprecation @JimGarrison. Are you using the word "interrupted" to talk about "stop" and "suspend"? Wow. I would encourage you to change the language given the overloaded term. – Gray Jul 24 '13 at 21:52
3

Rather than catching InterruptedException you can call Thread.interrupted() or Thread.getCurrentThread().isInterrupted() (the former will clear the interrupted flag, the latter will not), which will return true if the interrupted flag is set. You can only catch InterruptedException if you've called a method that throws it, like sleep

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
2

InterruptedException is only thrown from specific method calls - mostly any method calls that wait, sleep or do I/O, so it wont be thrown out of anywhere.

if the Thread youre trying to interrupt is doing something CPU-internsive and not I/O, you will need to sprinkle Thread.getCurrentThread().isInterrupted() calls in there otherwise the target thread might never notice.

radai
  • 23,949
  • 10
  • 71
  • 115