/* * class for bounded buffer, with synchronization */ public class BoundedBuffer { private Object[] buffer; private int nextToRemove; private int numElements; private boolean verbose = false; /* if true, verbose output */ public BoundedBuffer(int sz) { buffer = new Object[sz]; nextToRemove = 0; numElements = 0; } public BoundedBuffer(int sz, boolean verbose) { this(sz); this.verbose = verbose; } /* 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 { if (verbose) System.out.println("starting put with numElements = " + numElements); /* 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(); if (verbose) System.out.println("ending put with numElements = " + numElements); } /* 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 { if (verbose) System.out.println("starting get with numElements = " + numElements); /* 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(); if (verbose) System.out.println("ending get with numElements = " + numElements); return o; } /* Method to check whether buffer is empty. */ public synchronized boolean isEmpty() { return (numElements == 0); } }