views:

588

answers:

5

Hi all,

I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be breaked down in two questions:

  1. If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?

  2. If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?

+5  A: 

If you decide to integrate your code with other libraries, they can call interrupt() on your code. e.g. if you decide in the future to execute your code within an ExecutorService, then that may force a shutdown via interrupt().

To put it briefly, I would consider not just where your code is running now, but in what context it may run in the future. e.g. are you going to put it in a library ? A container ? How will other people use it ? Are you going to reuse it ?

Brian Agnew
A: 

The InterruptedException says that a routine may be interrupted, but not necessarily that it will be.

If you don't expect the interrupt then you should treat it as you might any other unexpected exception. If it's in a critical section where an unexpected exception could have heinous consequences, it might be best to try and clean up resources and gracefully shutdown (because getting the interrupt signals that your well-engineered application that doesn't rely on interrupts is being used in a way it wasn't designed, and so there must be something wrong). Alternatively, if the code in question is something non-critical or trivial, you might want to ignore (or log) the interrupt and keep going.

Ash
+3  A: 

The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt() on a Thread.

In practice, the normal use-cases for interrupt() involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.

Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit(). (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)

On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)

Stephen C
@Stephen: +1 but... Now I've got another question: is it good stackoverflow practice to open a new question? I've got a question related, but definitely not identical. Should I ask it here in a comment, edit my original question or simply ask a new question? (I'm a newbie)
Webinator
@OldEnthusiast - Ask a new question (and perhaps reference this). Otherwise the answers for this question will appear incorrect/incomplete etc.
Brian Agnew
+1  A: 

The problem with the question is "I". "I" usually refers to a single instance of a class. I mean by that, that any particular piece of low-level code (class) should not rely upon the implementation of the entire system. Having said that you do have make some "architectural" decisions (like what platform to run on).

Possible unexpected interrupts coming from the JRE are canceled tasks in java.util.concurrent and shutting down applets.

Handling of thread interrupts is usually written incorrectly. Therefore, I suggest the architectural decision to avoid causing interrupts where possible. However, code handling interrupts should always be written correctly. Can't take interrupts out of the platform now.

Tom Hawtin - tackline
Hi Tom, I remember your name from c.l.j.p. ;) Well, precisely: I never had to throw *interrupt()* myself... Unless I'm catching an InterruptedException and need to re-assert the interrupted status but this is still not 100% clear to me. I'm new here and surprised by the number of upvotes and answers/comments (both the correct ones and the wrong ones): obviously it's a subject that is not trivial or, at least, usually not well explained. That said thanks to all the posts I'm beginning to get a clearer picture of what's going on :)
Webinator
A: 

As already mentioned, another library can interrupt your threads. Even if the library doesn't have explicit access to the threads from your code, they can still get the list of threads that are running and interrupt them that way with the following method.

mangoDrunk