Reputation: 816
So I have a java object that executes wait()
and then another thread executes notifyAll()
on the same object.
When I initially tried this, it wouldn't work. It would throw an IllegalMonitorStateException
.
Thread refreshThread = new Thread(new Runnable() {
final Object dirtyLock = new Object();
public void run() {
while(true)
{
try
{
dirtyLock.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
refreshThread.start();
But if i surround the while(true)
loop with the following code, it works.
synchronized(dirtyLock){ /* while loop */ }
Now I had to do this in the function that notifies this thread to awake too.
synchronized(dirtyLock){ dirtyLock.notifyAll(); }
Does synchronized
give the thread ownership of the monitor object? How can two different threads claim ownership of the same monitor?
p.s. the question may sound dumb to some but I just want to learn how this behaviour works instead of just blindly coding.
Upvotes: 1
Views: 870
Reputation: 8295
Simply saying: synchronized(obj) {...}
let you get the obj's monitor, obj.wait()
gives up the monitor to let other threads have the chance to get the monitor, so you have get the monitor before you can give it up
Upvotes: 1
Reputation:
You can't wait() until you're holding the monitor.
For "old-school" Java concurrency (with the synchronized keyword as the main tool), then it works like this:
The synchronized(obj) { ... } construct only lets the thread which holds the monitor belonging to obj inside the block (or method) that's tagged with "synchronized". Only 1 thread can hold the obj's monitor at a time.
So, when threads try to enter the synchronized block (or method), only 1 will succeed. Any other threads which are trying must not enter the block.
So, by definition, when you're proceeding through a synchronized block, you are the thread that's holding the monitor of obj.
When you hit wait() then you have to go to sleep, and as you do so, you let go of the monitor. Other threads can now try to acquire it.
By the way, I can see what you're trying to do with the dirtyLock variable.
It already exists in Java - it's in a really awesome concurrency toolbox called java.util.concurrent (which ships with the JDK) - it's one of the real highlights of the platform and you should definitely use it, instead of trying to code this up from scratch. You can read loads about it online, or buy a book called "Java Concurrency in Practice" by Brian Goetz & co.
Upvotes: 1