import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class BoundedBuffer { private final Object[] content; private volatile int size; private volatile int next; private final Lock lock; private final Condition notFull; private final Condition notEmpty; public BoundedBuffer(int capacity) { this.content = new Object[capacity]; this.size = 0; this.next = 0; this.lock = new ReentrantLock(); this.notFull = this.lock.newCondition(); this.notEmpty = this.lock.newCondition(); } public void put(T value) throws InterruptedException { this.lock.lock(); try { while (this.size == this.content.length) { this.notFull.await(); } this.content[this.next] = value; this.size++; this.next = (this.next + 1) % this.content.length; this.notEmpty.signal(); } finally { this.lock.unlock(); } } public T get() throws InterruptedException { this.lock.lock(); try { while (this.size == 0) { this.notEmpty.await(); } int index = (this.next - this.size) % this.content.length; T value = (T) this.content[index]; this.size--; this.notFull.signal(); return value; } finally { this.lock.unlock(); } } }