Amit Kumar Gupta
Amit Kumar Gupta

Reputation: 7413

Where to call wait()

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

Answers (3)

Mark Peters
Mark Peters

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

bnguyen82
bnguyen82

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

Gray
Gray

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

Related Questions