class Data {}
public class Buffer {
    private int cap, free, first, last;
    private Data[] a;
    public Buffer(int n) {
        free = cap = n; first = last = 0;
        a = new Data[n];
    }
    public synchronized void produce(Data d) 
                        throws InterruptedException {
        if (free==0) wait(); free--; 
        a[last] = d; 
        last = (last+1) % cap;
        notify();
    }
    public synchronized Data consume() 
                        throws InterruptedException {
        if (free==cap) wait(); free++; 
        Data result = a[first]; 
        first = (first+1) % cap;
        notify();
        return result;
    }
} // end of class Buffer
