2

From all the resources I could pull together, I still cannot grasp thread interrupts.. From Oracle's own tutorials (https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html), they don't explain what causes the interrupt exception to be thrown, or how, or what it even is.. they just say it can happen whenever you invoke certain methods like Thread.sleep(). Does it randomly happen when it's called? Is there a length of time that it takes for the exception to be thrown? Is it thrown every time it's called? None of that makes sense because if it's random, it'd be useless to a programmer, and if it happens every time a certain method is called, it'd have no real use.. they explain very little about it, and just move on to other thread concepts.. I haven't had any issues with learning C, Lua, or Python, because the tutorials and documentation provided by them actually explains everything, this is the first time I've ever been completely stumped by a tutorial. I've been searching for about 2 hours for an answer.

Can you include what InterruptedException is exactly, and WHY it's thrown?

Aaron Flores
  • 81
  • 10

3 Answers3

7

From the first paragraph of the tutorial you link to:

A thread sends an interrupt by invoking interrupt on the Thread object for the thread to be interrupted.

This means interruption of Thread threadX is caused by any other thread calling threadX.interrupt().

It doesn't happen randomly - and any function that interrupts another thread will explicitly say so. (Mostly this is shutdown type functions on thread pools etc.)

Calls like Thread.sleep() watch for that call to interrupt() and respond by throwing an exception.

But if your thread doesn't call functions that watch for interruption by throwing InteruptedException - then you can watch for it using Thread.isInterrupted() (which is what the tutorial is about).

Here's an example of how you might use it. threadX is started and begins printing. The main thread (which starts threadX waits a little while then interrupts threadX, which will cause Thread.sleep() in threadX to throw an InterruptedException - threadX will then get a chance to print out its exit message.

   Thread threadX = new Thread( new Runnable() {
     public void run() {
       try {
       while(true) {
         Thread.sleep(100);
         System.err.println("In threadX");
       }
       } catch (InterruptedException e) {
         System.err.println("ThreadX interrupted and exiting...");
         // Restore the interrupted status 
         // not really needed here as we know the thread is exiting
         // but a good practice all the same. (So callers know 
         // we've been interrupted.)
         Thread.currentThread().interrupt();
       }
    }
  });

  threadX.start();
  Thread.sleep(1000);
  threadX.interrupt();

It's worth noting that if your function handles InterruptedException and doesn't rethrow it, (and doesn't cause the thread to immediately exit) then you should restore the intterupted state (which will have been cleared by the thrower of the InterruptedException) This way any callers know the thread has been interrupted. (Conversely if you throw an InterruptedException because you found inInterrupted() to be true you should first clear the interrupted state)

Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
  • Alright, thanks for finally giving me a good explanation :) My question now is, why use the exception if you could just use `Thread.isInterrupted()` to check and act upon the result? Could one just program without bothering with the exception and just use the method instead? – Aaron Flores Jun 09 '15 at 00:54
  • No you can't avoid using the `InterruptedException` if you call the functions that can throw it - especially as when they throw the `InterruptedException` they clear the state of `Thread.isInterrupted`. However you will want to use `Thread.isInterrupted()` if you dont regularly call out to such functions. (Definition of sufficiently regularly is up to the developer...) – Michael Anderson Jun 09 '15 at 01:00
  • 1
    @AaronFlores How do you check `isInterrupted` if you're blocked on an IO call? – Sotirios Delimanolis Jun 09 '15 at 01:02
  • Something like Thread.sleep() throws InterruptedException because otherwise there could be a very long delay before your code responds to the interruption. The InterruptedException will be thrown immediately when the interrupt happens, instead of after the normal sleep time is over. – Tony Jun 09 '15 at 01:06
  • One of the most important things to know is that you should reset the interupted state whenever you catch an InterruptedException: `catch (InterruptedException e) { // Restore the interrupted status Thread.currentThread().interrupt(); }` – Tony Jun 09 '15 at 01:07
  • Aaah, I get it now.. it would've taken just two lines to explain this in the tutorial lol. But thanks to you all for your help :) – Aaron Flores Jun 09 '15 at 01:10
  • 1
    @Tony - You should restore the interupted status, unless you know the thread is going to immediately exit. So no need for that in the example. But you're right I'll add it to the body. – Michael Anderson Jun 09 '15 at 01:11
  • For the question,'My question now is, why use the exception if you could just use Thread.isInterrupted() to check and act upon the result?' Sometimes, your code is not the owner of the thread, e.g when you use a thread pool, there is no chance for you to call Thread.interupe(). The only think you can do is to handle the InterruptedException in your code – Harry.Chen Jun 09 '15 at 03:40
3

You say:

they don't explain what causes the interrupt exception to be thrown, or how, or what it even is.. they just say it can happen whenever you invoke certain methods like Thread.sleep()

Thread interrupts happen when the interrupt() method of the Thread is called.

The reference to Thread.sleep() is in relation to handling the interrupt, not raising it. Some methods, such as Thread.sleep() throw InterruptedException, which gives you the programmer a chance to deal with the interrupt in whatever way you like.

If the thread never or rarely calls a method that throws InterruptedException then you can check the interrupted status of a thread by invoking Thread.interrupted(), and if true, take the appropriate action.

Raman
  • 17,606
  • 5
  • 95
  • 112
0

An interrupt comes from another thread. Like many other concurrent behaviors, it is "random" in that it MAY or MAY NOT happen during any particular method invocation, however it is not just a random thing that java sometimes does. Interrupts come from things like a user closing the application, or possibly in response to some nasty error condition where the application needs to shutdown. You can't know in advance whether this will happen during a particular method call, so you have to code against the possibility that it might happen.

Tony
  • 953
  • 1
  • 10
  • 22
  • Are you sure those things give the Thread a chance to handle `isInterrupted()`, or generate `InterruptionException`s? I thought `kill -9` and `System.exit()` would kill the application without any of those occurring. – Michael Anderson Jun 09 '15 at 00:50
  • That's why `kill -9 ` should be a last resort - it doesn't allow code to cleanly exit. `kill ` Sends an interrupt that code can handle. Somewhat off topic from your specific question, but good material on HOW to handle interupts can be found at http://www.ibm.com/developerworks/library/j-jtp05236/ and http://stackoverflow.com/questions/3976344/handling-interruptedexception-in-java – Tony Jun 09 '15 at 00:55
  • 1
    Signals don't cause interrupts, only interrupting a thread with Thread.interrupt() does. – Erwin Bolwidt Jun 09 '15 at 01:10
  • @ErwinBolwidt, didn't know that, thanks for the clarification. Apparently you use Runtime.getRuntime().addShutdownHook(...) to handle signals. – Tony Jun 09 '15 at 01:25