Java Reference
In-Depth Information
53 * get a dish that is only half full (or even empty).
54 */
55 synchronized (myDish) {
56 while (myDish.readyToEat == false) {
57 // wait for the ice cream man's attention
58 try {
59 System.out.println(name + msg);
60 myDish.wait();
61 } catch (InterruptedException ie) {
62 ie.printStackTrace();
63 }
64 }
65 myDish.readyToEat = false;
66 }
67 System.out.println(name +": yum");
68 }
69 }
70
71 class IceCreamDish {
72 public boolean readyToEat = false;
73 }
Line 55 synchronizes on the
IceCreamDish
reference,
myDish
. This means that the current
Child
thread will not move past line 55 until it has exclusive access to the
IceCreamDish
refer-
ence of this particular
Child
object.
Remember that each
Child
and the
IceCreamMan
share access to that particular child's
IceCreamDish
. The
IceCreamMan
could be modifying the
IceCreamDish
at any time; we don't
want the
Child
object to use the
IceCreamDish
until the
IceCreamMan
is through.
Now assume that the
Child
has achieved access to the
IceCreamDish
. This could happen
for two reasons. First, the
IceCreamMan
is not currently using that
Dish
(he does, after all, have
other
Child
objects to attend to). Second, the
IceCreamMan
is finished with that
Dish
. Line 56
checks the value of
dish.readyToEat
. This value tells the
Child
whether the
IceCream
is ready
to be eaten. A monitor is used between the
Child
objects and the
IceCreamMan
. Monitors will
be defined shortly. For now, think of a monitor as a prearranged signaling device between the
IceCreamMan
and the
Child
objects.
If the
dish.readyToEat
value is false, then the
IceCreamMan
has not finished filling the
bowl. The
Child
can release the lock on the
Dish
by calling
wait
on it, as in line 60.
Notice that the
Child
thread checks the condition of the
dish.readyToEat
variable in a
while loop, not an if statement. The reason for this is due to a small problem with when the
JVM will return control to the application after a call to the
wait
method. The Sun Javadoc
comments for the
wait
method say, in part: “
A thread can also wake up without being notified,
interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice,
applications must guard against it by testing for the condition that should have caused the
thread to be awakened, and continuing to wait if the condition is not satisfied. In other words,
waits should always occur in loops.
”