Thread question

J

John Resler

I know I'm being very general about a question that is very specific but
that's the way it goes. In the development of an application that is
multi-threaded, deadlock is always a problem and I'm having a problem with
the app I'm working on now. I got back into the books and solved part of the
problem but now I'm viewing some material and handling IPC (Inter-Thread
Communications in this case) and I'm curious about the language in "The Java
Programming Language, 3rd edition", Arnold, Gosling, Holmes.

In the threads chapter, there is a discussion of using the wait() call for
notification of completion by another thread. The statement says wait()
should always be placed in a loop rather than an if condition, eg:

synchronized void doWhenCondition() {
while(!condition)
wait();
// Do what must be done when condition is true.
}

My question is that, if I have a thread that waits, or a thread that sleeps,
they both can be notified by notify() or notifyAll(). In short, is it really
necessary to place a wait() call in a busy wait state, rather than a sleep()
state? Any opinions are appreciated.

-John Resler
WDMC
Wichita, Kansas
(e-mail address removed)
 
C

Carl Howells

John said:
My question is that, if I have a thread that waits, or a thread that sleeps,
they both can be notified by notify() or notifyAll(). In short, is it really
necessary to place a wait() call in a busy wait state, rather than a sleep()
state? Any opinions are appreciated.

Say what? wait() does NOT put the thread into a busy-wait state. Even
a small bit of testing would reveal this... A good book would explain
it in detail.
 
E

Eric Sosman

John said:
I know I'm being very general about a question that is very specific but
that's the way it goes. In the development of an application that is
multi-threaded, deadlock is always a problem and I'm having a problem with
the app I'm working on now. I got back into the books and solved part of the
problem but now I'm viewing some material and handling IPC (Inter-Thread
Communications in this case) and I'm curious about the language in "The Java
Programming Language, 3rd edition", Arnold, Gosling, Holmes.

In the threads chapter, there is a discussion of using the wait() call for
notification of completion by another thread. The statement says wait()
should always be placed in a loop rather than an if condition, eg:

synchronized void doWhenCondition() {
while(!condition)
wait();
// Do what must be done when condition is true.
}

My question is that, if I have a thread that waits, or a thread that sleeps,
they both can be notified by notify() or notifyAll(). In short, is it really
necessary to place a wait() call in a busy wait state, rather than a sleep()
state? Any opinions are appreciated.

This isn't a busy-waiting loop in any sense I've
ever encountered. Keep in mind that each wait() blocks
until some other thread calls notify() or notifyAll().
Hence, `condition' is evaluated only N+1 times, where N
is the number of externally-caused awakenings.

In general, the loop is necessary. As an illustration,
consider a simple producer-consumer situation, with a
queue holding the items produced but not yet consumed.
If the loop above is part of the consumer, it would by
synchronized on the queue object and `condition' would
be something like "queue is non-empty" (so `!condition'
means "queue is empty").

The consumer comes into this method to grab the next
Thing from the queue supplied by the producer. Let's say
it finds the queue empty and so puts itself to sleep by
calling wait(). Eventually the producer adds a new Thing
to the queue (synchronizing on it, of course) and calls
notify() to awaken the consumer. The consumer awakens,
and by the very fact of having been awakened can deduce
that the queue is now non-empty, right?

Wrong, R-O-N-G, wrong! The queue *was* non-empty when
the producer called notify(), but that was a while ago and
things may have changed. For example, there might be more
than one consumer thread running, and another consumer may
have taken the Thing from the queue before the first consumer
was fully awake -- while it was still rubbing sand from its
eyes, as it were. Or perhaps the "producer" and "consumer"
roles aren't quite so clear-cut, and the "producer" decided
to withdraw the just-produced Thing in response to a cancel
operation of some kind. The awakened consumer must re-test
the condition.

Here's the fundamental principle: You must hold the
lock on a shared resource while you inspect its state, lest
some other thread change that state while you're looking at
it. Furthermore, you can only rely on what you learned
from the inspection for as long as you continue to hold
the lock; the moment you release it, other threads have their
opportunity to get in and change things. Since wait() releases
the lock when it puts you to sleep and re-acquires it while
awakening you, nothing you thought you knew about `condition'
from the time before the lock was re-acquired is reliable.
You must re-test `condition' after wait() returns.
 

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,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top