这是线程安全队列的实现。push 和 pop 不会互相阻塞。但是,如果队列为空,pop 将等到一个项目被推送。多个生产者和消费者可以使用队列。如果您发现任何问题,请告诉我。
更新:根据答案编辑 1)解决了“队列已满”情况的问题。2).NET4中有BlockingCollection<T>
和ConcurrentQueue<T>
。所以没有必要重新发明轮子(对于.NET4)
public class CustomQueue<T> where T: class
{
class Node
{
public Node()
{
Value = null;
NextNode = null;
}
public Node(T value)
{
Value = value;
NextNode = null;
}
public T Value;
public Node NextNode;
}
object PushLocker = new object();
object PopLocker = new object();
Semaphore QueueSemaphore;
volatile int PushIncrement;
volatile int PopIncrement;
int MaxItems;
Node FirstNode;
Node LastNode;
public CustomQueue(int maxItems)
{
QueueSemaphore = new Semaphore(0, maxItems);
MaxItems = maxItems;
FirstNode = LastNode = new Node();
PushIncrement = 0;
PopIncrement = 0;
}
public int Size()
{
return PushIncrement - PopIncrement;
}
public bool Push(T value)
{
lock(PushLocker)
{
if((Size()) >= MaxItems)
{
lock(PopLocker)
{
PushIncrement = PushIncrement - PopIncrement;
PopIncrement = 0;
return false;
}
}
Node newNode = new Node(value);
LastNode.NextNode = newNode;
LastNode = newNode;
PushIncrement++;
QueueSemaphore.Release();
return true;
}
}
public T Pop()
{
QueueSemaphore.WaitOne();
lock(PopLocker)
{
Node tempFirst = FirstNode;
Node tempNext = FirstNode.NextNode;
T value = tempNext.Value;
tempNext.Value = null;
FirstNode = tempNext;
PopIncrement++;
return value;
}
}
}