import java.util.*; // A synchronized bounded queue which uses a "guard" // to ensure that we don't try to pop an empty queue // or push into a full one. Replacement for // SyncBoundedQueue. public class GuardedBoundedQueue extends BoundedQueue { public GuardedBoundedQueue(int size) { super(size); } synchronized public boolean isEmpty() { return super.isEmpty(); } synchronized public boolean isFull() { return super.isFull(); } synchronized public int getCount() { return super.getCount(); } synchronized public void push(Object obj) { try { while (isFull()) wait(); // wait for notify on this object } catch (InterruptedException e) {} super.push(obj); doNotify(); } synchronized public Object pop() { try { while (isEmpty()) wait(); // wait for notify on this object } catch (InterruptedException e) {} Object result = super.pop(); doNotify(); return result; } private void doNotify() { // Should use notifyAll() if there is a possibility // that more than one thread might be in a wait() // at this point. notifyAll() wakes up all waiting // threads, while notify() wakes up just one. // notifyAll() is less efficient but more correct // than notify(). notifyAll(); // Notifies all waiting threads //notify(); // Notifies one waiting thread } // Test driver (same as for SyncBoundedQueue) public static void main(String argv[] ) { GuardedBoundedQueue queue = new GuardedBoundedQueue(5); new Producer(queue,10).start(); new Consumer(queue,10).start(); } }