Threads3 (other files are same as before): ConsumerRow.java

import java.awt.*;

/**
 * This is like the old plain Row
 */
public class ConsumerRow extends Row implements Runnable { //*1 Uses a thread, like previous Row class
    private SupplyRow supply;

    public ConsumerRow (Rectangle loc, Canvas canvas, SupplyRow supply) {
	super (loc, canvas);
	this.supply = supply;

	// Start a new thread to run us
	Thread thread = new Thread (this);
	thread.start();
    }

    /**
     * Method for Runnable
     * Thread quits when it can't get another box
     */
    public void run () {
	while (true) {
	    // Try and get another box
	    Box b = supply.take (); //*2 Call special synchronized method to try to get a box

	    // If no more boxes, quit loop (and hence thread)
	    if (b==null) break; //*3 If no boxes, quit loop (and hence thread)

	    boxes.add (b);
	    // Since we just added to our list, need repaint
	    canvas.repaint ();

	    try {
		Thread.sleep (2000 + (int) (500 * Math.random ())); // 2-2.5 seconds
	    } catch (InterruptedException e) { }
	}
	System.out.println ("Row at y = " + loc.y + " finished");
    }
}
[download file]