Java Reference
In-Depth Information
49 synchronized (currentDish) {
50 currentDish.readyToEat = true;
51 //notify the dish's owner that the dish is ready
52 currentDish.notify();
53 }
54
55 //remove the dish from the queue of dishes that need service
56 dishes.remove(currentDish);
57 }
The synchronized blocks in lines 49-53 in the
IceCreamMan
's
serveIceCream
method here,
and lines 55-66 of the
Child
's
eatIceCream
method, require both threads to synchronize on the
same object. We have to assume that any programmers working on the
Child
class and the
IceCreamMan
class will continue to use the synchronized blocks. However, there is a risk that a
Child
may remove their synchronized code, which would mean that they could grab their dish
back before it has been filled with ice cream. This actually gives us a safeguard against the pro-
gram being changed—we can explain to other programmers that removing the synchronized
code could result in the
Child
thread getting a dish that has not been completely filled (or
could even be empty).
■
Tip
Whenever code is written that depends on a particular way of implementing it, you should add an
implementation comment to explain the details to other programmers. We have shown this in the comments
in lines 50-54 of the
Child
class in the previous code listing.
While it is relatively easy to explain to a
Child
that they should not try to take the plate
before they have been told it is full (because they won't want to miss out on more ice cream), it
is harder to get them to agree not to try to hand their dishes over all at once—from their per-
spective the sooner they hand the dish over the sooner it will be filled. They don't particularly
care about fairness to the other children, or how well the
IceCreamMan
can handle receiving
multiple plates at once.
To guard against this, we have synchronized the
IceCreamMan
's
requestIceCream
method.
By synchronizing the method, we can ensure that only one
Child
is ever handing a dish to the
IceCreamMan
at a time.
59 /**
60 * Allow client objects to add dishes
61 */
62 public synchronized void requestIceCream(IceCreamDish dish) {
63 dishes.add(dish);
64 }
65