import java.util.Random;

/**
 * A consumer gets at most ITERATION elements from the buffer.
 *
 * @version     1.1    February 7, 2000
 * @author      Franck van Breugel
 * @see Buffer
 */
public class Consumer extends Thread 
{
    private static int consumers = 0;    // number of consumers

    public static final ThreadGroup CONSUMERS = new ThreadGroup("Consumers");

    private Buffer buffer;               // the buffer from where this consumer gets its elements
    private int id;                      // number of this consumer

    /**
     * Constructs a consumer which gets elements from the specified buffer.
     *
     * @param buffer The buffer from where this consumer gets its elements.
     */
    public Consumer(Buffer buffer)
    {
        super(CONSUMERS, "consumer");
        this.buffer = buffer;
        setId(this);
    }

    /**
     * Sets the number of the specified consumer.
     *
     * @param consumer The consumer whose number is set.
     */
    private static synchronized void setId(Consumer consumer)
    {
        consumers++;
        consumer.id = consumers;
    }

    /**
     * If this consumer is the last consumer to stop, then all producers
     * are signalled to stop.
     */
    private static synchronized void finish()
    {
        consumers--;
        if (consumers == 0)
	{
            Producer.PRODUCERS.interrupt();
	}
    }

    /** Maximal number of elements to be taken from the buffer. */
    private static final int ITERATION = 20;

    /** Maximal delay in miliseconds */
    private static int MAX_DELAY = 9999;

    /** Gets at most ITERATION integers from the buffer and prints them. */
    public void run() 
    {
	Random generator = new Random();

        boolean isInterrupted = false;
        int i = 0;
        while (i < ITERATION && !isInterrupted) 
        {
            try
            {
                System.out.println("Consumer " + id + " has gotten " + (Integer) buffer.get());
                Thread.sleep((long) 1 + generator.nextInt(MAX_DELAY));
            }
            catch (InterruptedException e) 
            {
                isInterrupted = true;
            }
            isInterrupted |= isInterrupted();
            i++;
        }
        if (!isInterrupted)
        {
            finish();
	}
    }
}

