|      | Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form | 
 
In this example, theProducergenerates an integer between 0 and 9 (inclusive), then stores it in a
CubbyHoleobject. To make the synchronization problem more interesting, the
Producersleeps for a random amount of time between 0 and 100 milliseconds before repeating the number-generating cycle.Thepublic class Producer extends Thread { private CubbyHole cubbyhole; private int number; public Producer(CubbyHole c, int number) { cubbyhole = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(number, i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }Consumerconsumes all integers from the
CubbyHole(the exact same object into which theProducerput the integers in the first place) as quickly as they become available.Thepublic class Consumer extends Thread { private CubbyHole cubbyhole; private int number; public Consumer(CubbyHole c, int number) { cubbyhole = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get(number); } } }ProducerandConsumerexamples share data through a commonCubbyHoleobject. Although, ideally,Consumerwill get each value produced once and only once, neitherProducernorConsumermakes any effort whatsoever to ensure that this happens. The synchronization between these two threads occurs at a lower level within thegetandputmethods of theCubbyHoleobject. Assume for a moment, however, that the two threads make no arrangements for synchronization; let's discuss the potential problems that might arise from this.One problem arises when the
Produceris quicker than theConsumerand generates two numbers before theConsumerhas a chance to consume the first one. In this situation, theConsumermisses a number. Part of the output might look like the following figure.Another problem might arise when the 
Consumer misses number.
Consumeris quicker than theProducerand consumes the same value twice. In this situation, theConsumermight produce the output shown in the following figure.Either way, the result is wrong because the 
Consumer gets the same number twice.
Consumershould get each integer produced by theProducerexactly once. A problem like this is called a race condition. A race condition is a situation in which two or more threads or processes are reading or writing some shared data, and the final result depends on the timing of how the threads are scheduled. Race conditions can lead to unpredictable results and subtle program bugs. Race conditions in the producer-consumer example are prevented by having storage of a new integer in theCubbyHoleby theProducersynchronized with retrieval of an integer from theCubbyHoleby theConsumer. The activities of theProducerand theConsumermust be synchronized in two ways.First, the two threads must not simultaneously access the
CubbyHole. A thread can prevent this from happening by locking an object. When an object is locked by one thread and another thread tries to call a synchronized method on the same object, the second thread will be blocked until the object is unlocked.Second, the two threads must do some simple coordination. That is, the
Producermust have a way to indicate to theConsumerthat the value is ready, and theConsumermust have a way to indicate that the value has been retrieved. TheObjectclass provides a collection of methods wait,notify, andnotifyAll to help threads wait for a condition and to notify other threads when that condition changes.
 
|      | Start of Tutorial > Start of Trail > Start of Lesson | Search Feedback Form | 
Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.