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

