0

Consider the following code from java.util.concurrent.locks.AbstractQueuedSynchronizer as one of the many examples of the idea presented in the title:

1258    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws Interrupted Exception {
1259        if (Thread.interrupted())
1260            throw new InterruptedException();
1261        return tryAcquireShared(arg) >= 0 ||
1262            doAcquireSharedNanos(arg, nanosTimeout);
1263    }

Why do most blocking library methods respond to interruption by calling the static method Thread.interrupted() instead of instance method isInterrupted() . Calling the static method also clears the interrupted status so if even the task handling code swallows the InterruptionException , there is no way for the callers to get to know about the interrupted status other than

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Geek
  • 26,489
  • 43
  • 149
  • 227
  • Because, if it's even true, which is not proven, that's the way the authors wrote them. Ask the authors. You're asking in the wrong place. Not constructive. – user207421 Jul 16 '12 at 10:42

3 Answers3

5

It is always true that if you catch an InterruptedException, the interrupted flag has already been cleared. The exception itself is your signaling mechanism at that point. The catcher is required to either re-enable the flag or take care directly that the thread moves to a close.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • "It is always true that if you catch an InterruptedException, the interrupted flag has already been cleared." Thats precisely what library mehtods do like in the example here..But my question was why do they clear the status ?They could have just polled for the status by calling isInterrupted() method ? – Geek Jul 16 '12 at 09:36
  • 1
    But why? As soon as that query does clear the flag, the method throws `InterruptedException`. Why do the extra step? Do you dispute the contract of `InterruptedException` by thinking that the flag should remain set, even though the exception is thrown? But that's not the point of the flag. – Marko Topolnik Jul 16 '12 at 09:37
  • Yes I do not see why that flag needs to be cleared . What happens if the caller of any task swallows the interruption ? There is now way to check for the interruption status at all except from the caller calling `Thread.currentThread().interrupt()` ...If the caller accidentally swallows the InterruptedException there is every chance that it will fail to call `Thread.currentThread().interrupt()` also . – Geek Jul 16 '12 at 09:47
  • 1
    If the caller swallows the exception, he has violated the contract of the interruption mechanism. The main cause of that happening in practice is `InterruptedException` being a checked exception, forcing everyone calling an interruptible operation to deal with it, even if he hasn't got the first idea what it is. But it's obvious what the designers of the mechanism had in mind. – Marko Topolnik Jul 16 '12 at 09:50
1

Basically, it seems that you think that the API / behavioural contract should be different, and you want to know why "they" designed it the way it is, and not your preferred way.

We can't answer that. Nobody here was "in the room" when the issues were debated and the decisions were made. If you want a definitive answer, you will need to track down the original designers and ask them.

And the question is moot anyway ... unless you are planning on designing and implementing your own programming language.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • To be fair, it is a very fragile design. Similar to `clone`. It suffers from the "weakest link" syndrome. – Marko Topolnik Jul 16 '12 at 09:51
  • @MarkoTopolnik - and to be fair, I've yet to see any (workable) design that does any better. There are fundamental problems in this area that can't be fixed without ditching Java's entire concurrency model and starting again. (And AFAIK all other thread-based concurrency models have the same fundamental problems.) – Stephen C Jul 16 '12 at 09:57
  • 2
    No silver bullet, but `InterruptedException` being unchecked and the flag not being cleared by default would make the system more robust to mishandling. – Marko Topolnik Jul 16 '12 at 10:00
  • @MarkoTopolnik - that changes the problem from "doesn't respond to interrupts" to "crashes"; i.e. you replace one problem with another (worse) one. The root problem here is that interruption requires the cooperation of the interrupted thread, and that is a fundamentally HARD problem with a Java-like threading model. – Stephen C Jul 16 '12 at 23:23
  • In 99% of real-world cases an exception doesn't crash anything since there's an exception barrier in the app anyway. The handling code will do pretty much what's needed for proper interruption semantics -- do the cleanup and abort the current task. – Marko Topolnik Jul 17 '12 at 08:25
1

The answer to the question in the title is "Because implementing Runnable does not expose isInterrupted() directly". Obviously it is simple to access the flag without affecting it through Thread.currentThread().isInterrupted() but that is not the point here. The point is it is deliberately easier to use Thread.interrupted() because that is what you should mostly do.

Your complaint about code that uses Thread.interrupted

If you are checking whether your thread has been interrupted you should be at a point in your code where you are able to do something about it, otherwise what is the point? The mechanism defined deliberately discourages you from quietly exiting your loop. It is specifically encouraging you to deal with the interrupt and deliberately encourages you handle it by throwing it.

It is the code that calls isInterrupted that is suspect, not the code that calls interrupted. You should not consider handling an interrupt quietly, you should handle it dramatically or not at all. It is the Thread.currentThread.isInterrupted() callers that are quietly absorbing the exception and therefore causing the problem, not the callers of Thread.interrupted().

Please see Dr. Heinz M. Kabutz on Shutting down threads cleanly for a more authoritative discussion.

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213