Reputation: 531
I want to start with IllegalMonitorStateException which we get if the current thread is not the owner of the object's monitor. So if I do this, I will get exception:
public class Testing {
Object objLock = new Object();
void dance(){
synchronized (this){
objLock.wait();
}
}
}
So I came to conclusion that you must have same object to synchronize and call wait/notify. Does that mean I can only have one condition per lock?
But then there is Condition class and Lock interface. How do they manage to solve the job?
public class Testing {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void dance(){
lock.lock();
condition.await();
lock.unlock();
}
}
Before I learn something wrong, does this mean that Lock/Condition example allows us to have more conditions? And how come when I just showed example of IllegalMonitorStateException which prevents us from doing exactly that. Can someone please explain my confusion? How did Condition class 'trick it'? Or did it, if I said something wrong?
Upvotes: 3
Views: 138
Reputation: 3236
First of all, lets see official documentation of Conditions:
Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.
And according to official doc of Lock:
Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects.
So, using this information I will answer your questions:
does this mean that Lock/Condition example allows us to have more conditions?
Yes, you can use more than one condition per lock and create your synchronizing logic using the combination of conditions. See example from official doc.
The reason you did get IllegalMonitorStateException
is that you attempted to wait for object while not having a monitor for it (you should have passed objLock
as synchronized block parameter). The reason you didn't get it with second code example is that you do not perform illegal wait operation on objects while not having monitor for them. You lock the resources by calling lock.lock()
and unlock them after some condition is satisfied. Until that, no other threads can access those resources. Clearly, there is no magic or trick behind it.
P.S.: I recommend you to read documentation pieces on Lock
and Condition
as I find them really useful and informative in case of your question.
Upvotes: 2