01: import java.util.concurrent.locks.*;
02: 
03: /** 
04:     A first-in, first-out bounded collection of objects. 
05: */ 
06: public class BoundedQueue<E>
07: { 
08:    /** 
09:        Constructs an empty queue. 
10:        @param capacity the maximum capacity of the queue 
11:    */ 
12:    public BoundedQueue(int capacity) 
13:    { 
14:       elements = new Object[capacity]; 
15:       head = 0; 
16:       tail = 0; 
17:       size = 0;
18:    } 
19: 
20:    /** 
21:        Removes the object at the head. 
22:        @return the object that has been removed from the queue
23:    */ 
24:    public E remove() throws InterruptedException
25:    { 
26:       queueLock.lock();
27:       try
28:       {         
29:          while (size == 0) 
30:             valueAvailableCondition.await();
31:          E r = (E) elements[head]; 
32:          head++;
33:          size--;
34:          if (head == elements.length) 
35:             head = 0; 
36:          spaceAvailableCondition.signalAll();
37:          return r; 
38:       }
39:       finally
40:       {
41:          queueLock.unlock();
42:       }
43:    } 
44: 
45:    /** 
46:        Appends an object at the tail. 
47:        @param newValue the object to be appended 
48:    */ 
49:    public void add(E newValue) throws InterruptedException
50:    { 
51:       queueLock.lock();
52:       try
53:       {         
54:          while (size == elements.length) 
55:             spaceAvailableCondition.await();
56:          elements[tail] = newValue; 
57:          tail++;
58:          size++;
59:          if (tail == elements.length) 
60:             tail = 0; 
61:          valueAvailableCondition.signalAll();
62:       }
63:       finally
64:       {
65:          queueLock.unlock();
66:       }
67:    } 
68: 
69:    private Object[] elements; 
70:    private int head; 
71:    private int tail; 
72:    private int size;
73: 
74:    private Lock queueLock = new ReentrantLock();
75:    private Condition spaceAvailableCondition 
76:          = queueLock.newCondition();
77:    private Condition valueAvailableCondition 
78:          = queueLock.newCondition();
79: }