illegalMonitorStateException

M

morizn

hello everybody!

it is well known that one has to be in the monitor of an object to call
myObj.wait(), f. E. by putting it into a synchronize(myObj) block.

my questions:
- is it bad programming style to just catch the exception without doing
the synchronize? because if i do this my program still perfectly does
what it should.
- why does this exception exist?

thanx a lot,
moritz.
 
A

Antti S. Brax

it is well known that one has to be in the monitor of an object to call
myObj.wait(), f. E. by putting it into a synchronize(myObj) block.

Do you understand what you say? Read the API docs for that
excpetion. Especially the part: "Thrown to indicate that a
thread has attempted to wait on an object's monitor or to
notify other threads waiting on an object's monitor without
owning the specified monitor."
my questions:
- is it bad programming style to just catch the exception without doing
the synchronize? because if i do this my program still perfectly does
what it should.

If you call wait without owning the monitor you WILL get that
exception.

Now, since you did not get the exception and did not provide
any sample code I guess that you already are in a code block
that is synchronized with that object as the monitor.

You may have acquired the monitor before entering the method
where you call wait.
- why does this exception exist?

Read the API doc. After that execute the following code:

public class Test {
public void testWait() throws Exception {
Object o = new Integer(42);
o.wait();
}
public static void main(String args[]) throws Exception {
Test t = new Test();
t.testWait();
}
}
 
A

Antti S. Brax

it is well known that one has to be in the monitor of an object to call
myObj.wait(), f. E. by putting it into a synchronize(myObj) block.

my questions:
- is it bad programming style to just catch the exception without doing
the synchronize? because if i do this my program still perfectly does
what it should.
- why does this exception exist?

In my earlier post I assumed that you knew what the wait() method
does. Sorry.

Why are you calling Object.wait() when you have no idea about what
the method does?!

Read the API for Object.wait() and ask more in comp.lang.java.help.
 
J

John C. Bollinger

morizn said:
hello everybody!

it is well known that one has to be in the monitor of an object to call
myObj.wait(), f. E. by putting it into a synchronize(myObj) block.

my questions:
- is it bad programming style to just catch the exception without doing
the synchronize? because if i do this my program still perfectly does
what it should.

Yes, it is terrible style. In fact, either your program does _not_ do
what it should when you ignore these, or you have written code that is
inconsistent with what your program should do. This is frequently the
case with catching RuntimeExceptions, but especially so with
IllegalMonitorState exception: if a wait() invocation throws it then it
indicates that the invoking thread did not wait, and therefore was not
notify()ed to resume. (Instead it simply continued.)
- why does this exception exist?

Because multithreaded programs would be many times more difficult to
debug without it. They're already hard enough with it.
 
M

morizn

thanks for your answer. you're right, i could have pointed out more
exactly what my problem is. look at the following code:

public class Test {
public static void main(String[] args) {
Object sync = new Object();

Receiver r = new Receiver(sync);
Sender s = new Sender(sync);
}
}

class Sender extends Thread {
Object sync;

public Sender(Object s) {
sync = s;
start();
}

// generating a Signal
public void run() {
for (int i=0; i<10; i++) {
try {
sleep(1000);
synchronized (sync) {
sync.notifyAll();
}
}
catch (Exception e) {
}
}
}
}

class Receiver extends Thread {
Object sync;

public Receiver(Object s) {
sync = s;
start();
}

public void run() {
while (true) {
try {
synchronized (sync) {
sync.wait();
}
}
catch (Exception e) {
}
System.out.println("Signal Received.");
}
}
}

if i remove the synchronized around the wait in the receiver thread, it
doesn't wait at all.
i do know that only one thread can get into the monitor of sync at one
time. but what do the monitors have to do with the wait method? why did
the java developers expect the wait method to be inside a synchronized
statement?

ok, i appreciate any help but i don't like comments like "In my earlier
post I assumed that you knew what the wait() method does. Sorry. "

thanx,
moritz.
 
C

Chris Smith

morizn said:
thanks for your answer. you're right, i could have pointed out more
exactly what my problem is. look at the following code:

I'm looking:
catch (Exception e) {
}

Don't do that. When you catch Exception, you are catching an incredibly
large class of erro conditions, many of which you certainly don't
understand. Instead, if you wish to catch IllegalMonitorStateException
and InterruptedException, then catch those types, and let all other
exceptions true. (My suspicion, though, is that you really don't want
to catch IllegalMonitorStateException at all. See below.)

If you do enough of the kind of catch block above, you will end up
writing programs that don't crash because you've caught the exception,
but do corrupt data because you didn't recover from the exception. If
the program crashes, the user only has to run it again. If it corrupts
data, you could cost the user thousands of dollars or more trying to
recover. The user will then curse your name for all of eternity. I'm
told it's no fun to have someone cursing your name for all of eternity.
It's always better to crash than to corrupt data. Even code posted to
this newsgroup is imitated by people learning Java, and then makes it's
way into production, causing the above mentioned name-cursing.
if i remove the synchronized around the wait in the receiver thread, it
doesn't wait at all.

Right. It throws IllegalMonitorStateException, which you then catch and
ignore so that it *looks* like it just didn't wait. I presume from
context that you knew this already?
i do know that only one thread can get into the monitor of sync at one
time. but what do the monitors have to do with the wait method? why did
the java developers expect the wait method to be inside a synchronized
statement?

You need to be in a 'synchronized' block to wait() and notify() because
otherwise it's impossible to use the methods correctly. You would
always end up with a race condition between the waiting thread and the
notifying thread, where the notifying thread could call notify() just
moments *before* the waiting thread sleeps, and you lose a signal. To
avoid that, you need to use synchronized *AND* a predicate. You are
halfway there.

The predicate is, simply put, what you are waiting for. The notifying
thread first sets the predicate, and then sends the notification. The
waiting thread first checks the predicate, and then waits only if it has
something to wait for. When it's done waiting, it checks the predicate
again to be sure that it has really finished waiting. This is generally
accomplished with a while loop.

To revise your code:

public class Test
{
/* The predicate for the sample wait/notify below. */
public static boolean avail = 0;

public static void main(String[] args)
{
Object sync = new Object();

new Receiver(sync);
new Sender(sync);
}
}

class Sender extends Thread
{
Object sync;

public Sender(Object s)
{
sync = s;
start();
}

// generating a Signal
public void run()
{
for (int i=0; i<10; i++)
{
try
{
sleep(1000);
synchronized (sync)
{
Test.avail++;
sync.notifyAll();
}
}
catch (InterruptedException e)
{
}
}
}
}

class Receiver extends Thread
{
Object sync;

public Receiver(Object s)
{
sync = s;
start();
}

public void run()
{
while (true)
{
synchronized (sync)
{
while (Test.avail == 0) sync.wait();
Test.avail--;
}

System.out.println("Signal Received.");
}
}
}

As for IllegalMonitorStateException, if it occurs then you have a bug in
your code. There is no possible user input or normal error condition
that should be able to cause your program to throw an
IllegalMonitorStateException. For that reason, you almost certainly
don't want to catch it; and if you do catch it, you certainly don't want
to ignore it. You need to abort the entire operation you're working on
(which might be the entire program) to the point that you're certain
that the state of the application is consistent again.

You also need to log the exception so that you get some kind of
indication of this bug. Depending on how much control you have over the
client, I've even sometimes included the ability to email a bug report,
so that I really do find out when these things occur if the user is okay
with it.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

morizn

hi chris,

thanks so much for your answer.
i really do understand the thing about exception catching, and also
that wait() didn't wait without the synchronized statement because of
the exception.

you said:
"You need to be in a 'synchronized' block to wait() and notify()
because
otherwise it's impossible to use the methods correctly. You would
always end up with a race condition between the waiting thread and the
notifying thread, where the notifying thread could call notify() just
moments *before* the waiting thread sleeps, and you lose a signal."

perhaps the problem is that i see the methods wait() and notifyAll() as
atomic routines which they aren't. is the reason for the synchronized
that a thread could interrupt the wait() method with a notifyAll()
method while the wait() method is still not finished?

moritz.
 
C

Chris Smith

morizn said:
perhaps the problem is that i see the methods wait() and notifyAll() as
atomic routines which they aren't. is the reason for the synchronized
that a thread could interrupt the wait() method with a notifyAll()
method while the wait() method is still not finished?

Nope, not quite. You need take on small step back from that
perspective. When you call wait(), you are waiting for *something* to
happen in another thread. That might be waiting for another thread to
finish preparing some data for you, or waiting for another thread to
finish using a resource that you need. You would then call wait() only
if what you're waiting for isn't done yet. That implies two steps:

A. Check if the thing you're waiting for is done yet.
B. If not, then wait.

The problem is this sequence of events:

1. You finish A, and find that the thing you're waiting for is not done
yet. Your thread is preempted (e.g., end of time slice) before you get
to B.

2. The other thread finishes the thing you're waiting for. It calls
notify(), but that call doesn't do anything because no threads are
waiting right now.

3. Your thread gets a time slice again, and calls wait(). It will now
hang in wait() forever, because the notify() that it was waiting for has
already occurred.

You see? The problem is not with wait(), but with the combination of
checking the predicate (i.e., the thing you're waiting for) and wait
itself.

The other thing I mentioned is that, for a number of reasons, it's not a
good idea to try to use the occurrence of notify() as the predicate
itself. That's true for two distinct reasons: first, because you can't
generally guarantee that one thread will reach wait() before the other
reaches notify(), and second, because of something called spurious
wakeups, which means that your thread may return from wait() before
notify() is ever called. Instead, you want an explicit predicate, and a
loop like this:

while (!predicate()) wait();

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

morizn

thanks a lot chris, your explination was great.
i didn't think of spurious wakeups, so using wait without a predicate
doesn't make sense. and thus, using it without synchronize also
doesn't.

again, thanks a lot for your answer!

moritz.
 
C

Chris Smith

morizn said:
thanks a lot chris, your explination was great.
i didn't think of spurious wakeups, so using wait without a predicate
doesn't make sense. and thus, using it without synchronize also
doesn't.

again, thanks a lot for your answer!

You're welcome. Just a little nit, though.

Predicates would be required even without spurious wakeups. Otherwise,
you still have the possibility that the notifying thread finishes its
work and calls the notify() method before the other thread gets around
to calling wait(). You may think this is unnecessary if your notifying
tasks will take several seconds... but remember that another maintenance
programmer will certainly come after you and optimize some special case
so that it completes in negligible time, and then the software will lock
up intermittently and it will ultimately be your fault because you
depended on probable behavior for the correctness of your code.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top