我是新來的整個循環/環緩衝思維方式。我閱讀了一些關於它如何在理論上工作的文章,並提出了這個代碼示例。在我的場景中,我將有多個線程寫入和從緩衝區讀取單個線程。CircularBuffer,我需要添加鎖嗎?
我需要一個鎖添加到寫入方法?
在此先感謝!
public class CircularBuffer<T>
{
private readonly int _size;
private int _head;
private byte _headMirrorSide;
private int _tail;
private byte _tailMirrorSide;
private readonly T[] _buffer;
public CircularBuffer() : this(300) { }
public CircularBuffer(int size)
{
_size = size;
_buffer = new T[_size + 1];
_head = 0;
_headMirrorSide = 0;
_tail = 0;
_tailMirrorSide = 0;
}
private bool IsFull()
{
return _tail == _head && _tailMirrorSide != _headMirrorSide;
}
public bool IsEmpty()
{
return _tail == _head && _tailMirrorSide == _headMirrorSide;
}
private void MovePointer(ref int pointer, ref byte mirrorSide)
{
pointer = pointer + 1;
if (pointer == _size)
{
mirrorSide ^= 1;
pointer = 0;
}
}
public void Write(T obj)
{
_buffer[_head] = obj;
if (IsFull())
{
MovePointer(ref _tail, ref _tailMirrorSide);
}
MovePointer(ref _head, ref _headMirrorSide);
}
public T Read()
{
var obj = _buffer[_tail];
_buffer[_tail] = default(T);
MovePointer(ref _tail, ref _tailMirrorSide);
return obj;
}
}
編輯:最終的結果是這樣的。
public class CircularBuffer<T> where T : class
{
private readonly int _size;
private int _head;
private byte _headMirrorSide;
private int _tail;
private byte _tailMirrorSide;
private readonly T[] _buffer;
private readonly object _lock = new object();
public CircularBuffer() : this(300) { }
public CircularBuffer(int size)
{
_size = size;
_buffer = new T[_size + 1];
_head = 0;
_headMirrorSide = 0;
_tail = 0;
_tailMirrorSide = 0;
}
private bool IsFull()
{
return _tail == _head && _tailMirrorSide != _headMirrorSide;
}
private bool IsEmpty()
{
return _tail == _head && _tailMirrorSide == _headMirrorSide;
}
private void MovePointer(ref int pointer, ref byte mirrorSide)
{
pointer = pointer + 1;
if (pointer == _size)
{
mirrorSide ^= 1;
pointer = 0;
}
}
public void Write(T obj)
{
lock (_lock)
{
_buffer[_head] = obj;
if (IsFull())
{
MovePointer(ref _tail, ref _tailMirrorSide);
}
MovePointer(ref _head, ref _headMirrorSide);
}
}
public T Read()
{
lock (_lock)
{
if (IsEmpty())
{
return null;
}
var obj = _buffer[_tail];
MovePointer(ref _tail, ref _tailMirrorSide);
return obj;
}
}
}
製作一個循環緩衝區線程安全和等待釋放是一個簡單的練習1個生產者和1名消費者。但是在這種情況下你的代碼甚至不安全。支持多個作家更復雜。 –
重點關注你真正需要什麼,以及爲什麼不是ConcurrentQueue。 –
我需要一個有限的FIFO列表,其功能是如果達到限制,「舊」值將被覆蓋。環形緩衝區不應該滿足這些要求嗎? – mckn