Consider following code. Do you see the problem? Try executing it
public class MyClass {
private Boolean myObj = true;
public static void main(String[] args) {
MyClass a = new MyClass();
a.callMe();
}
public MyClass() {
}
public void callMe() {
synchronized (myObj) {
myObj = false;
myObj.notifyAll();
}
}
}
You will see
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at MyClass.callMe(MyClass.java:18)
at MyClass.main(MyClass.java:8)
Now try replacing callMe() code with following
public void callMe() {
synchronized (myObj) {
myObj.notifyAll();
myObj = false;
}
}
Wondering about why its working fine now!
that's because when you do following
myObj = false;
Now myObj is pointing to different immutable object of type Boolean with value false. Its not the object on which you synchronized and hence when you call notify on the new object referenced by myObj, it throws exception saying you don't own monitor for this object. You owned monitor of a object which was being reference before the assign statement
Suggestion: follow best practices. At least use only final objects for acquiring lock
Thanks! helped me in saving time :)
ReplyDelete