最近有個小功能,需求是多線程寫,單線程讀。
考慮採用AtomLong作爲寫的指針,用一個2的N次方長度的數組作爲Buffer的存儲,超出後自動循環,不擴容。
讀由於是單線程,採用普通long作爲指針即可。
代碼如下:
private T[] buffer;
private int remMask;
private long readPointer=0;
private AtomicLong writePointer=new AtomicLong(0);
public NolockObjectBuffer(int bufferSizeTimes,Class<T> clz) {
buffer = (T[])Array.newInstance(clz,1<<bufferSizeTimes);
remMask = buffer.length-1;
}
@Override
public List readBufferData() {
long start=readPointer;
long end=writePointer.get();
while(end-start>buffer.length){
start=end-buffer.length;
}
List<T> result=new ArrayList<T>((int)(end-start));
for(long i=start;i<end;i++){
result.add(buffer[getBufferPos(i)]);
}
readPointer=end;
return result;
}
private int getBufferPos(long pointer){
return (int)pointer&remMask;
}
@Override
public void putBufferData(T data) {
buffer[getBufferPos(writePointer.getAndIncrement())]=data;
}
@Override
public Stream<T> stream() {
long start=readPointer;
long end=writePointer.get();
List<T> result=new ArrayList<T>((int)(end-start));
for(long i=start;i<end;i++){
result.add(buffer[getBufferPos(i)]);
}
return result.stream();
}
比如統計遠程接口調用的平均耗時,用Buffer記錄每個請求的訪問耗時,然後定期Get一下進行最大、最小、平均的計算。