When should a method throw InterruptedException, and how should I handle one that does? (blocking method) When should a method throw InterruptedException, and how should I handle one that does? (blocking method) multithreading multithreading

When should a method throw InterruptedException, and how should I handle one that does? (blocking method)


No, I don't find your summary to be correct. Usually, if you're writing a method that calls on others that throw InterruptedException, then your method should also advertise throwing InterruptedException—unless you have a good plan for what to do when the methods on which yours relies signal interruption.

The cases where you'll be able to absorb such interruption are rare. Perhaps you're computing an iterative solution, where the precision increases with time, but, upon your calling thread being interrupted, you decide that the solution you've reached in the allotted time is good enough, and is still correct enough to return. In other words, that solution is still within your method's range.

Imagine:

private double improveUpon(double start) throws InterruptedException {  // ...}public double compute() {  double result = 0.0;  try {    do {      result = improveUpon(result);    } while (couldBeImproved(result));  } catch (InterruptedException ex) {    Thread.currentThread().interrupt();  }  return result;}

Alternately, if you merely want to respect an interruption request, you can do so without InterruptedException being involved:

private double improveUpon(double start) {  // ...}public double compute() {  final Thread current = Thread.currentThread();  double result = 0.0;  do {    result = improveUpon(result);  } while (couldBeImproved(result) &&           !current.isInterrupted());  return result;}

For yet another variation, consider the case where your method must either complete all its work or indicate to the caller that it could not complete it, and it takes a while to get there, but you want to respect thread interruption. Something like this will suffice:

private double improveUpon(double start) {  // ...}public double compute() throws InterruptedException {  final Thread current = Thread.currentThread();  double result = 0.0;  do {    if (current.interrupted())      throw new InterruptedException();    result = improveUpon(result);  } while (!isAdequate(result));  return result;}

Note there that we called on Thread#interrupted(), which has the side effect of clearing the thread's interruption status if it had been set. If that method returns true, we as the caller have accepted the responsibility to hold and communicate that interruption status. In this case, since we do not assume that we created the calling thread and we don't have enough scope visible here to know what its interruption policy is, we communicated the interruption status we observed and adopted by throwing InterruptedException.

Labeling a method as "blocking" is always a matter of degree; every method blocks its caller for some amount of time. The distinction you may be looking for is whether the method blocks waiting on some external input, such as a user pressing a key or a message arriving over a network. In those cases, advertising that you throw InterruptedException indicates to your caller that your method is safe for use by callers from threads that must control their latency. You're saying, "This may take a while to complete, but it will take no longer than you're willing to wait." You're saying, "I'll run until you tell me not to." That's different from, say, java.io.InputStream#read(), which threatens to block until one of three conditions occur, none of which is the caller's thread being interrupted.

In most cases, your decision comes down to answering the following questions:

  • To satisfy my method's requirements, do I need to call on any methods that throw InterruptedException?
  • If so, is the work I've done up to that point of any use to my caller?
  • If not, I too should throw InterruptedException.
  • If nothing I call throws InterruptedException, should I respect my calling thread`s interruption status?
  • If so, is any work I've done up to the point at which I detect that I've been interrupted of any use to my caller?
  • If not, I should throw InterruptedException.

The situations in which one will detect the current thread's interruption and swallow it are usually confined to those where you, the author, created the thread in question, and you have committed to exiting the thread's run() method once the thread gets interrupted. That's the notion of "cooperative cancellation," wherein you observe the request for your thread to stop running, and you decide to abide by that request by finishing your work as quickly as possible and letting the thread's call stack unwind. Again, though, unless you're the author of the thread's run() method, you swallowing the thread's interruption status is likely harming the intended behavior of your callers and of the other methods upon which they call.

I suggest that you study the topic of a thread's interruption status, and get comfortable with the methods Thread#isInterrupted(), Thread#interrupted(), and Thread#interrupt(). Once you understand those, and see that an InterruptedException being in flight is an alternate representation of Thread#isInterrupted() having returned true, or a courteous translation of Thread#interrupted() having returned true, this should all start making more sense.

If you need more examples to study, please say so and I can add recommendations here.


InterruptedException is (usually) thrown when thread blocked on a method gets interrupt() called on it.

The point of it is to unblock (for some reason) a thread that is blocked. Example of reason is application shutdown. So, when you shutdown your application, if you have threads waiting on let say sleep() or wait() , if you do not tell them that you are shutting down they will continue to wait(). If those threads are not daemon threads, then your application won't shutdown.

So, when thread gets interrupted during sleep(), you have to check the conditions and handle the situation. In case of shutdown, you have to check your shutdown flag and eventually do the clean-up work and let the thread go.

Threads can be interrupted because of some other reasons, but the point is the same.If you have multi-threaded application you have to establish protocol for your threads so that they know when there is some special condition how to handle it. In case the thread is waiting/sleeping, you have to wake it up to handle the situation.The clinets of your library or framework do not know anytrhing about your protocol, so they don't know how to handle InterruptedException because of that the recomendation is to handle it in your library/framework code.


If your method blocks, it should catch and handle InterruptedException, and prefer not to re-throw it.

Also, the method may block in several places - each place should catch and handle InterruptedException in a way appropriate for the place where it could be thrown.

The bible on the subject of multi-threaded code is Java Concurrency in Practice. I highly recommend you read it.

Edited:

When designing your concurrent code, realise that:

  • According to the JVM spec, InterruptedException may be thrown randomly by the JVM for no reason at all (known as a "spurious wakeups")
  • Many threads may be waiting on the same condition, all may be woken (eg by notifyAll()), but only one may advance when interrupted

so whenever a thread is woken, it should check the state of the wait condition it is waiting for and potentially go back to waiting.

Thus, properly written concurrent code should catch InterruptedException. You can chose to re-throw it or throw your own application-specific exception. "Application code" methods should prefer to throw "application" exceptions, however if your waiting code may find itself in a state where it's not possible to figure out "what went wrong", then your only option is to throw InterruptedException.