Reputation: 7413
In my java program, when I code
synchronized(a){
a = 55;
a.wait();
}
It gives run time exception java.lang.IllegalMonitorStateException
on a.wait();
statement. However a=55
runs successfully.
But if I code as
synchronized(a){
a.wait();
a = 55;
}
then it runs perfectly without any exception. why so?
Upvotes: 0
Views: 68
Reputation: 81074
Because a
is pointing to a different object after reassignment, and is not being synchronized on.
In other words, there are two objects, val1
and val2
that are both assigned to the variable a
. You synchronize on val1
but in the first example call wait on val2
. The monitor you use is attached to the object, not its variable.
You should thus avoid synchronizing by referencing a non-final variable. This leads to your confusion. If the field is mutable, use another lock, for example:
Object aMonitor = new Object();
synchronized(aMonitor) {
a = 55;
aMonitor.wait();
}
Ideally your scenario is just for learning though. wait()
and notify()
are primitives and shouldn't be used unless as an exercise or for building your own concurrency library. If it's for real code, use a higher level mechanism in java.util.concurrent
.
Upvotes: 3
Reputation: 6248
In the first case, variable a (after assigned to a new integer) is not the "a" that's been locked by synchronized(a), so calling a.wait() results an exception.
Upvotes: 0
Reputation: 116878
Because you have replaced the object a
when you do the assignment. This is called auto-boxing. a = 55
actually creates a new Integer
object so then when you call a.wait()
on it, it is waiting on a different object that you have not synchronized on which is why you get the exception.
As I mentioned in the answer to your other question, you cannot assign an object inside of a synchronized
block. Even the following pattern is a bad idea because then you assign a
to a different object, it means the next thread to call synchronized
will be doing so on a different a
so 2 threads can be in the same synchronized
block at the same time.
synchronized(a){
a.wait();
// still a bad idea
a = 55;
}
Upvotes: 2