7

If using following "idiom" with interruption in Java, for example from this answer.

while (!Thread.currentThread().isInterrupted()) {
    try {
        Object value = queue.take();
        handle(value);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

Where take is a blocking operation, can an interrupt not be ignored for the time being if an interrupt "arrives" between the check of Thread.currentThread().isInterrupted() and the call queue.take()? Is this not a "check-than-act" operation? If so, can it somehow be guaranteed that the loop is left in any case if the thread is interrupted?

It is possible to use poll with a timeout so that the loop is left after the timeout, but is it possible to check the interrupted status and act on it atomically?

Community
  • 1
  • 1
user140547
  • 7,750
  • 3
  • 28
  • 80
  • 2
    How could an interrupt ever be missed by the above code? You realize that queue.take() will throw immediately if the thread is interrupted before the call to take(), right? – JB Nizet Jun 10 '16 at 07:35
  • @JBNizet: I have checked the code, and you are right, methods throwing `InterruptedException` check for the interupted status first and throw. If you add an answer, I'll accept it. – user140547 Jun 10 '16 at 08:13

3 Answers3

3

I would swap the try/catch and while loop:

try {
  while (true) {
    Object value = queue.take();
    handle(value);
  }
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
}

The take() operation will throw an InterruptedException immediately if the thread is interrupted, and at the same time break out of the while loop.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • In the interrupt comes during handling, the exception may not be thrown. So - for sake of to be sure, I usually use while (!Thread.currentThread().isInterrupted()) – gusto2 Jun 10 '16 at 07:38
  • @GabrielVince Please explain the circumstances under "the exception may not be thrown". – Andy Turner Jun 10 '16 at 07:42
  • in case the "handle(..)" method is doing some computations, not necessarily waiting for I/O and the thread is interrupted, The exception is not thrown. I'd check it in the loop. I wouldn't assume the blocking I/O will throw an exception when the thread is entering with already interrupted state (though the comment from JB.Nizet states otherwise and I may be wrong here). – gusto2 Jun 10 '16 at 07:51
  • @GabrielVince The `handle()` function appears to be defined in the same class that you are editing. It will throw an `InterrutpedException` if you change it to check the flag and throw the exception. – Solomon Slow Jun 10 '16 at 13:57
0

Only a call could clear then interrupted flag so nothing could happend between isInterrupted and queue.take().

robinr
  • 4,376
  • 2
  • 20
  • 18
0

but is it possible to check the interrupted status and act on it atomically

Well - I don't know what you mean "atomically" here. May we assume you want something like onInterrupt(...)?

Interrupts are meant to "interrupt" the thread, so all default I/O operations throw an InterruptedException you can catch or check. It give the threads opportunity to stop gracefully closing / releasing any locked resources.

As event handling you may want to implement a Cancellable task, where you could handle your own cancel events (well, not the default JRE interrupts).

gusto2
  • 11,210
  • 2
  • 17
  • 36