Reputation: 6364
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
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: -
this
reference.Example (Synchronized block) : -
synchonized(obj) { // Locks `obj`
obj.wait(); // Invoke wait on obj
}
Upvotes: 2
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