views:

441

answers:

5

A teammate made the following claim: "Thread.interrupt() is inherently broken, and should (almost) never be used". I am trying to understand why this is the case.

Is it a known best practice never to use Thread.inerrupt()? Can you provide evidence why it is broken / buggie, and should not be used for writing robust multithreaded code?

Note - I am not interested in this question if it's "pretty" from a design preservative. My question is - is it buggy?

+3  A: 

The main problem with Thread.interrupt() is that most programmers don't know about the hidden pitfalls and use it in the wrong way. For example, when you handle the interrupt, there are methods which clear the flag (so the status gets lost).

Also, the call will not always interrupt the thread right away. For example, when it hangs in some system routine, nothing will happen. In fact, if the thread doesn't check the flag and never calls a Java method which throws InterruptException, then interrupting it will have no effect whatsoever.

Aaron Digulla
A: 

THe problem is not that the implementation is not buggy but rather your thread is in an unknown state when it gets interrupted and this can lead to unpredictable behavior.

Brian Ensink
Are you perhaps thinking of Thread.stop() ?
Robert Munteanu
Interrupting is graceful signalling, its not pausing or aborting the thread.
Will
Ah yes, my mistake. Stop is the evil one. Thanks!
Brian Ensink
+8  A: 

The only way I'm aware of in which Thread.interrupt() is broken is that it doesn't actually do what it seems like it might - it can only actually interrupt code that listens for it.

However, used properly, it seems to me like a good built-in mechanism for task management and cancellation.

I recommend Java Concurrency in Practice for more reading on the proper and safe use of it.

Sbodd
+4  A: 

Short version:

Is it a known best practice never to use Thread.interrupt()?

No.

Can you provide evidence why it is broken / buggie, and should not be used for writing robust multithreaded code?

The opposite is true: it is critical for multithreaded code.

See Listing 7.7 in Java Concurrency in Practice for an example.

Longer version:

Around here, we use this method in one specific place: handling InterruptedExceptions. That may seem a little strange but here's what it looks like in code:

try {
    // Some code that might throw an InterruptedException.  
    // Using sleep as an example
    Thread.sleep(10000);
} catch (InterruptedException ie) {
    System.err.println("Interrupted in our long run.  Stopping.");
    Thread.currentThread().interrupt();
}

This does two things for us:

  1. It avoids eating the interrupt. The classic textbook code always shows you a print or log message that makes note of the interrupt and then, effectively, ignores it.
  2. It passes the interrupt along without forcing a checked exception on this method.

When you receive an InterruptedException, someone is trying to stop the application or thread. If you don't respond to that request, you have effectively created an unkillable zombie thread.

Bob Cross
The sleep() only gets interrupted if someone interrupts it; in your handler, you just demote the checked exception into an unchecked one. Ouch.
Will
@Will, that's the point: I accept the interrupt and then force the interrupt to continue. If I simply had a "throws InterruptedException" clause on the method, anyone with a "catch (Exception e) {}" block would eat the exception. Sleep gets interrupted on a control-C: if you eat the exception, your thread won't stop.
Bob Cross
Great illustration!
erickson
@erickson, Thanks - I added the link to the listing just now. I never realized that they'd put the code samples up on the JCIP site. That should come in very handy!
Bob Cross
+2  A: 

No, it's not buggy. It actually is the basis of how you stop threads in Java. It's used in the Executor framework from java.util.concurrent - see the implementation of java.util.concurrent.FutureTask.Sync.innerCancel.

As for failure, I've never seen it fail, and I've used it extensively.

Robert Munteanu
Exactly. It's very important that code checks for interruption if you intend to use it in a cancellable task. There's nothing "evil" about `interrupt`; it is still depended on heavily by experts like Doug Lea.
erickson