user1870400
user1870400

Reputation: 6364

wait() call in java code

public class newTest{

/**
 * @param args
 */
public static Integer x = new Integer(0);

public static void main(String[] args) {
    newTest tstobj = new newTest();
    // TODO Auto-generated method stub
    MyThread t = tstobj.new MyThread();
    t.start();
    tstobj.incrementX();
    System.out.println(x.intValue());
    try {
        t.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public synchronized void incrementX(){
    try {
        while(x != 5){
            x.wait();
        }
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}



public class MyThread extends Thread{
    newTest tstobj = new newTest();
    public void run() {
        // TODO Auto-generated method stub      
        tstobj.incrementX();
    }
}

}

I am not sure why this code results in a IllegalMonitorStateException rather than infinite loop. In specific this code has two threads 1. main thread 2. MyThread both of them try to call a synchronized method called incrementX() so lets say one of the two threads enters a synchronized method by acquiring a lock and then it sees that x != 5 so it calls wait which will release the lock and will be placed on a waiting queue and the next thread which is waiting to call the synchronized method will enter by acquiring a lock and see that x != 5 and calls wait which will suspend the thread and placed into the waiting queue. Now two threads are in the waiting queue doing nothing which should result in an infinite loop. but this code results in a illegalMonitorStateException?

This code will not do anything useful but i wanted understand where am i going wrong conceptually? I looked into lot of material but still couldn't figure out whats wrong with my expectations of the code. Any help would be great. Thanks

Upvotes: 1

Views: 174

Answers (2)

Rohit Jain
Rohit Jain

Reputation: 213203

Just change your wait call to: -

wait();  // or `this.wait()

You can only invoke wait and notify methods on the object that you have locked. So, when you call that synchronized method, you will actually lock the object pointed to by this reference. So, you need to invoke wait() on this reference.

Here are two rules you can follow whenever using wait and notify methods: -

  • A synchronized method always locks on this reference.
  • A synchronized block can lock any reference, depending upon which object reference you are using in the parenthesis.

Example (Synchronized block) : -

synchonized(obj) {    // Locks `obj`
    obj.wait();       // Invoke wait on obj
}

Upvotes: 2

Narendra Pathai
Narendra Pathai

Reputation: 41935

For calling wait() on some object first you have to get lock for that object. so first

synchronize(x){

    //some code

    x.wait();

}

Upvotes: 0

Related Questions