// ---- Class for bounded buffer, with synchronization --------------- public class BoundedBuffer { // Instance variables. private Object[] buffer; private int nextToRemove; private int numElements; // Constructor. public BoundedBuffer(int sz) { buffer = new Object[sz]; nextToRemove = 0; numElements = 0; } // Method to put "itm" into buffer. // Waits if buffer is full; wakes up all waiting threads on exit. // Allows exceptions thrown by wait() to bubble up. public synchronized void put(Object o) throws InterruptedException { // wait until not full while (numElements == buffer.length) wait(); int next = (nextToRemove + numElements) % buffer.length; buffer[next] = o; ++numElements; // Wake up any waiting threads, since some might be waiting // for "buffer not empty". notifyAll(); } // Method to get item from buffer and return. // Waits if buffer is empty; wakes up all waiting threads on exit. // Allows exceptions thrown by wait() to bubble up. public synchronized Object get() throws InterruptedException { // wait until not empty while (numElements == 0) wait(); Object o = buffer[nextToRemove]; nextToRemove = (nextToRemove + 1) % buffer.length; --numElements; // Wake up any waiting threads, since some might be waiting // for "buffer not full" notifyAll(); return o; } }