why isn't a thread waiting for an object lock responsive to interruption? i did some search and read interuppting blocked thread. I understand arguments like in java, only methods can be forced to throw exceptions and the synchronized blocks cannot be forced throw an exception etc. But this kind of waiting-for-lock behavior seems to be an obvious cause for deadlocks, so why cant language specification make the synchronized blocks throw interrupted exception and make the developer handle it? is there any strong reason language specification wise to not do this? Also the answer says interrupts are not only stopping/cancelling threads. If that is so why is Lock.lockInterruptibly() introduced later?
Asked
Active
Viewed 368 times
-1
-
Could you post the relevant code? – Ali Feb 24 '17 at 05:28
1 Answers
2
The whole point of the synchronized
keyword is to be simple (or at least, as simple as multithreading can be). This is explicitly stated at Oracle's Java tutorial on Lock objects:
Synchronized code relies on a simple kind of reentrant lock. This kind of lock is easy to use, but has many limitations. More sophisticated locking idioms are supported by the
java.util.concurrent.locks
package.
One of those limitations is the lack of ability to interrupt a waiting thread.
Basically, the design principle is that if you just need the simplest form of mutual exclusion, synchronized
is fine; if you need anything more than minimum, you need to use one of the other, more sophisticated tools.

yshavit
- 42,327
- 7
- 87
- 124
-
2...and because of all that, you should design your code so that no thread ever holds a `synchronized` lock for any longer than it takes to update a few fields. – Solomon Slow Feb 24 '17 at 14:31
-
I agree with the answer. I am not confused about the behavior. What i didn't understand was: this "forever-try-to-lock" behavior seemed to lead to easy deadlocks and no recovery. I cannot wait for a timeout and interrupt.If its an obvious source for deadlocks then language designers would have thought about a way out it. One solution I could think of was to interrupt(assuming interrupting is the best possible way to stop a thread). I wanted to understand if there was a strong reason why no solution was given for this problem by language design earlier. Or May be my assumptions are wrong. – Thiru Feb 25 '17 at 04:36
-
Well it can only deadlock of you're accessing multiple locks at once, first of all. And the language designers did think of a way out of that: the aforementioned more sophisticated constructs. In a lot of cases, all you want is a simple way to set some fields atomically, or something similarly simple, and in those cases it's nice to have an easy construct that does just what you need, and not more. – yshavit Feb 25 '17 at 05:43
-
Here's another way to think about it. This interrupt ability you want, how would it look? If you're concerned about deadlocks, then you're dealing with multiple locks, and need a way to specify which you want to use -- like an object reference, for instance. Then you need to specify how to acquire it: normal, interruptibly, with a timeout, etc -- sounds like a method call. Then you need to always release it -- sounds like a try-finally. So your more advanced `synchronized` is starting to look a lot like a Lock object with a try-finally. – yshavit Feb 25 '17 at 05:58
-
sorry to pull this longer just trying to understand- say if the language spec forces every synchronized block to be covered by a try-catch block catching InterruptedException, and JVM throws this exception for the waiting thread when interrupted during wait, this could have been solved earlier?what is the problem with this approach? – Thiru Apr 04 '17 at 11:12
-
1There's no inherent problem to it. It's just a more sophisticated use case, and it would force that complexity on even simple uses. Once they JLS designers knew there would be simple use cases (like just writing to a few fields, but doing it atomically) and complicated use cases (using `Object.wait`, etc, and later the `java.util.concurrent.*` classes as an intermediate level of complexity). So they had to draw a line _somewhere_ for what constitutes a simple case -- and they chose full mutex, no interruptibility. Could they have chosen something else? Sure. It was a judgement call. – yshavit Apr 04 '17 at 14:26