You want the Consumer to get each integer produced by the Producer exactly once. Problems, such as those just described, that arise from multiple, asynchronously executing threads trying to access a single object at the same time and getting the wrong result, are called race conditions . The Consumer must consume each integer exactly once. Monitors Objects such as the CubbyHole, which are shared between two threads and whose accesses must be synchronized, are called condition variables . The Java language allows you to synchronize threads around a condition variable through the use of monitors .
Monitors prevent two threads from simultaneously accessing the same variable.
Here's a small stand-alone Java application that creates a CubbyHole object, one Producer, one Consumer, and then starts both the Producer and the Consumer. Here's the output of ProducerConsumerTest. Recompile the program and run it again. Because no explicit effort has been made to synchronize the Producer and Consumer threads, the Consumer consumes with reckless abandon and gets a whole bunch of zeros instead of getting each integer between 0 and 9 exactly once.