Re: IllegalMonitorStateException?
"Dan Maloney" <ddmalon@gmail.com> wrote in message
news:C98Ii.588$W76.378@newsfe12.lga...
<snipped prelude>
| > | Only one thread at a time can own an object's monitor.
| > |
| > | Throws: IllegalMonitorStateException - if the current thread is not
the
| > | owner of this object's monitor.
| > |
| > | In the context of my program, I don't understand how to do that. What
| > | modifications do I need to make this work?
| >
| > A key point of synchronization is that the object on which you call wait
/
| > notify must be exactly the same object instance of a synchronization
block
| > that wraps around the call--thereby ensuring that you can only invoke
wait /
| > notify / etc on an object whose monitor you already own. You can setup
a
| > synchronization block like this:
| >
| > synchronized (anObject) {
| > // ... your stuff, etc, etc
| > anObject.wait ();
| > }
| Matt, thank you for your advice, you provided me the right information
| to get me past my misconception. For some reason, I thought that only
| the wait() needed to be in a sychronized block and the notifyAll() was
| somehow aware of ALL waits that were in sychronized blocks and then
| notify all of them. I now understand that the notifyAll() must also be
| in a sychronized block and sychronized on the same object as the wait().
| By putting both the wait() and notifyAll() in sychronized blocks and
| sychronized on the same object, I got my program to work.
You're welcome. The trick behind synchronize / wait is that it makes
threads that are getting ready to wait mutually exclusive with the thread
that is getting ready to notify (or whatever) so that you can properly
manage race conditions and complex wait conditions. When you perform notify
or notifyAll, you're guaranteed that waiting threads are either fully
outside of the synchronization area or they are already waiting. The
waiting thread releases the monitor when (after) it enters the wait state.
Once the monitor is released, other threads that are blocked on the monitor
will proceed.
You should next consider making your condition for waiting explicit and
performing your wait inside a loop that tests the condition. There are
several reasons for this, but my favorite is that wait can be notified
(sometimes spurriously) by someone other than your notify. Without an
explicit condition your wait may complete too soon and cause terrible
problems. (Or worse, it won't exhibit problems on your development / test
machine but will certainly fail for your customer.) So it's more common to
see wait used like this:
boolean isSignalled = false;
synchronized (lock) {
while (! isSignalled) {
lock.wait (); // try, catch, etc.
}
// Ok, we've truly been signalled. Reset flag and proceed
isSignalled = false;
}
-------------
synchronized (lock) {
isSignalled = true;
lock.notifyAll ();
// I prefer notifyAll in case someone else's naughty
// code is also waiting on my object and possibly
// eats up my notify.
}
Java's new concurrency classes (well, they're not so new anymore) probably
already have classes to do this kind of signalling, but I learned it the
old-fashioned way.
Good luck with your project,
Matt Humphrey http://www.iviz.com/