|
|
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
In this example, theProducergenerates an integer between 0 and 9 (inclusive), 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.public 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); } } }ProducerandConsumerexample share data through a commonCubbyHoleobject. AlthoughConsumerideally will get each value produced once and only once, neitherProducernorConsumermakes any effort whatsoever to ensure that happens. The synchronization between these two threads occurs at a lower level, within thegetandputmethods of theCubbyHoleobject. However, assume for a moment that these two threads make no arrangements for synchronization, and 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 this:Another problem might arise when the Consumeris quicker than theProducerand consumes the same value twice. In this situation, theConsumermight produce output that looks like this:Either way, the result is wrong because the Consumershould get each integer produced by theProducerexactly once. A problem such as 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 the storage of a new integer into theCubbyHoleby theProducerbe synchronized with the retrieval of an integer from theCubbyHoleby theConsumer. The activities of the Producer and 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 block 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 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.