img
. .
change the condition, and send you a wakeup. You reacquire the synchronized section, retest the
condition, etc.
Example 6-15 Using wait/notify (Java)
Thread 1
Thread 2
synchronized (object) {
while (!object.my_condition)
object.wait();
synchronized (object) {
object.my_condition = true;
object.notify();
// object.notifyAll();
}
do_thing();
}
Whereas in POSIX mutexes and condition variables exist as separate data types that must be
associated together by the programmer, in Java they are tightly integrated with each object. As we
mentioned, every Java object has associated with it a mutex, and additionally every Java object
has associated with it a condition variable. The class Object defines the methods wait(),
notify(), and notifyAll() to manipulate the condition variable associated with that object.
These correspond directly to pthread_cond_wait(), pthread_cond_signal(), and
pthread_cond_broadcast().
An object's condition variable is always associated with the object's mutex. Hence, before you can
invoke wait() on the object, you must hold the mutex--that is you must be in a synchronized
statement referring to that object. Unlike POSIX, Java also requires that you hold the object's
mutex before doing a notify() or notifyAll(). This may make notify() and
notifyAll() slightly less efficient due to the extraneous contention for the mutex (see below),
but the extra cost is minimal.
It is legal to call notify() at any time whatsoever (as long as the mutex is held). It's not very
useful to call it unless you have changed some aspect of the condition being tested, but it's never
wrong. It will never cause a bug in your program. Moreover, it is always legal to call
notifyAll() instead of notify(). (The opposite is not true.) At worst, it will waste a bit of
time while the extra threads wake up, realize there's nothing for them to do, and go back to sleep.
We'll have more to say about this soon (see Condition Variables vs. wait/notify).
As with synchronized sections, there is no defined wakeup order for wait/notify. And also as with
synchronized sections, it doesn't matter. You have a job and you want some thread to wake up and
do that job--you don't care which thread.
Extraneous Contention
Because of the kind of interaction that exists between the condition variable and its associated
mutex, it is possible to get some unwanted contention for the mutex. This is most evident when
calling broadcast. Unfortunately, there is not much you can do about it, and your program may
well suffer dozens of microseconds in wasted mutex blocks.
Figure 6-11 illustrates the problem. In the "Desired Behavior" case, the little bit of extra time it
takes for T2 to wake up and try for the mutex is just long enough for T1 to release it. In the
"Possible Behavior" case, the waiting threads wake up, try for the mutex, and have to go right
back to sleep because the mutex hasn't been released yet. The most obvious solution for at least
some of this problem is to make the call to signal or broadcast outside the critical section. This is
what all of our POSIX code does.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home