Overview

In this lab we will:

A. Threads in Java

Take a copy of the Java source code files Producer.java, Consumer.java, CubbyHole.java and ProducerConsumer.java. Open the files in your favourite editor and have a read of them. Try to understand what each does. Basically, two threads are created, a producer and a consumer. The producer repeatedly attempts to put an item in the "cubbyhole" (it can hold only one item) and the consumer repeatedly tries to take an item from the cubbyhole.

Problems will arise unless the threads are synchronised and cooperate with one another. For example, what if the producer writes two items in quick succession to the cubbyhole before the consumer has had a chance to remove the first one? Some data will be lost. What if the consumer removes data before the producer has put any new data in? It will get the same data twice. What if the cubbyhole is concurrently accessed by both threads? We may suffer lost updates.

Such behaviour illustrates a lack of synchronisation. Running the code we can verify it does not work properly and you may see something like the following (as we can see there is no alternate turn-taking by producer and consumer):

$ javac Consumer.java Producer.java CubbyHole.java ProducerConsumer.java
$ java ProducerConsumer
Producer #1 put: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Producer #1 put: 1
Producer #1 put: 2
Producer #1 put: 3
Producer #1 put: 4
Producer #1 put: 5
Producer #1 put: 6
Producer #1 put: 7
Producer #1 put: 8
Producer #1 put: 9

B. Solving the problem

Take a copy of this annotated version of CubbyHole.java. Follow the directions in the comments and insert the code necessary to fix the problems identified above. Run your new program and verify it now works as expected.

C. Testing multithreaded applications

From the few runs you carried out above it seems the program is working correctly. But can we be sure? Not really, unmet race conditions could arise in the future causing your program to malfunction. To avoid such errors you need to program carefully and think about the code you write (like in your assignment). One thing you might try, in a bid to force errors to the surface, is adding multiple producer and consumer threads. Try it.

D. Bored?

You could do worse than go through the Java concurrency tutorial linked from the course home page.