今天看了一下同事的环形缓存,在百度了一下,发现大多数都是在比较读/写位置,我觉得这样不适合我,首先读/写位置比较逻辑比较复杂。
然后动手写了一个适合自己的(逻辑简单),但我写的这个也有个弱点:浪费内存 :-(
代码如下:
/**
* 环形缓冲区<br/>
* 一. 写数据:<br/>
* 1. push: 当数据已写满时返回false,否则可以正常写入返回true<br/>
* 2. pushNoCaseFull: 不管缓冲区是否已写满或当前位置数据是否已读取过,都会写入,不关心读/写指针位置<br/>
* 二. 读数据:<br/>
* 1. pull: 当缓冲区已读空或还未写入过数据时,返回null<br/>
* 另外一个重载方法可以对指定位置进行读取,此方法不会影响读指针位置<br/>
* 2. pullNoCaseEmpty: 不管当前位置的数据有没有读过,即可以重复读,不关心读/写指针位置,不会影响读指针位置<br/>
* 另外一个重载方法可以对指定位置进行读取,此方法不会影响读指针位置<br/>
* 3. pullBack: 反相读取数据,返回数据情况与pull相同<br/>
* 4. pullBackNoCaseEmpty: 反相读取数据,返回数据情况与pullNoCaseEmpty相同<br/>
* 三. 是否已写满:<br/>
* isFull: 如果写之前关心是否已满,调用此方法<br/>
* 四. 是否已读空:<br/>
* isEmpty: 读数据之前关心是否已读空,调用此方法<br/>
*/
public class RingBuffer<T> {
private final static byte INVALID = ~0;// 无效数据
private final static byte WRITED = 0;// 数据写过
private final static byte READED = 1;// 数据读过
private int mCapacity = 0;
private List<Node> mDataBuf = null;
private int mReader = 0;
private int mWriter = 0;
private class Node {
public T object = null;
public byte flag = INVALID;
public Node(T object, byte flag) {
this.object = object;
this.flag = flag;
}
}
public RingBuffer(int capacity) {
mCapacity = capacity;
mDataBuf = new ArrayList<Node>(capacity);
}
/**
* 当数据已写满时返回false,否则可以正常写入返回true<br/>
* @param object 被压入的数据
* @return true: 写入成功, false:缓冲区已满
*/
public synchronized boolean push(T object) {
int size = mDataBuf.size();
if (mWriter < mCapacity) {
}
else if (mWriter >= mCapacity) {// 写到尾部
mWriter = 0;