Java Reference
In-Depth Information
threads or the IceCreamMan thread could have started running immediately afterwards. In
addition, yielding is something you would normally do before you start (or in the middle of )
a lengthy or complex task—it is a way of being nice to other threads. However, this is not the
case here. Finally, if there are no other threads that can run, the JVM will immediately pass
control back to the while loop—this will result in the thread consuming as much CPU cycles
as are available; it can even lead to your computer having the appearance of hanging.
The serveIceCream method is the most interesting part of our code. Assuming that there is
currently a Dish in the queue, line 49 synchronize s on that IceCreamDish instance. This has the
effect of forcing any Child objects that want to use the IceCreamDish instance to wait. Specifi-
cally, it causes line 55 in Child to pause until line 53 in IceCreamMan is reached or, if the Child
thread had paused at line 60, it will not be able to resume until line 53 in IceCreamMan is
reached.
Conversely, if a Child instance is executing a method that synchronize s on the
IceCreamDish , then hitting line 49 in IceCreamMan will cause IceCreamMan to wait until lines 50
through 61 in Child finish executing, or until the Child instance releases the lock on the Ice-
CreamDish by calling wait in line 55.
This is an example of the threads respecting each other's boundaries. By synchronizing on
the same object, the two threads can be assured that they will not be simultaneously modify-
ing or using the same object.
When the IceCreamMan owns the lock on the dish, he can fill it with ice cream, and then
notify the Child that it is available. This happens in line 52. After line 52 is run, the Child
thread that was waiting on that particular plate will no longer be waiting—the JVM scheduler
will now be able to run it. However, until the IceCreamMan releases the lock on the dish at the
completion of line 53, the Child will not be able to regain the lock on the dish, so it will remain
blocked.
Note You cannot call the notify method on an object unless you are in a block or a method that is
synchronized on that object.
34 /**
35 * Serve Ice Cream to a Child object.
36 */
37 private void serveIceCream() {
38 // get an ice cream dish
39 IceCreamDish currentDish = dishes.get(0);
40
41 // wait sometimes, don't wait sometimes
42 if (Math.random() > .5) {
43 delay();
44 }
45
46 String msg = "notify client that the ice cream is ready";
47 System.out.println("IceCreamMan: " + msg);
48
Search WWH ::




Custom Search