package com.github.rfqu.ringBuffer.threaded; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class RingBuffer<T> { int bufSize; Object[] entries; Cursor writeWindow; Cursor readWindow; public RingBuffer(int bufSize) { this.bufSize = bufSize; entries=new Object[bufSize]; writeWindow=new WriteCursor(); readWindow=new ReadCursor(); } abstract class Cursor { protected long position; private final Lock lock = new ReentrantLock(); private final Condition posChanged = lock.newCondition(); int waitCount=0; @SuppressWarnings("unchecked") public T get(long position) { return (T)entries[(int)(position%bufSize)]; } public void set(long position, T object) { entries[(int)(position%bufSize)]=object; } public abstract void waitLimit(long position2) throws InterruptedException; public abstract long getLimit(); public long getPosition() { lock.lock(); try { return position; } finally { lock.unlock(); } } /** not for public use */ void waitPosition(long position2) throws InterruptedException { lock.lock(); try { while (position2>=position) { waitCount++; posChanged.await(); } } finally { lock.unlock(); } } public void setPosition(long position) { lock.lock(); try { this.position=position; posChanged.signal(); } finally { lock.unlock(); } } } class WriteCursor extends Cursor { public long getLimit() { return readWindow.getPosition()+bufSize; } public void waitLimit(long limit) throws InterruptedException { readWindow.waitPosition(limit-bufSize); } } class ReadCursor extends Cursor { @Override public long getLimit() { return writeWindow.getPosition(); } @Override public void waitLimit(long limit) throws InterruptedException { writeWindow.waitPosition(limit); } } }