Here is an implementation of a thread safe queue. The push and pop won't block each other. However, pop will wait until an item is pushed, if the queue is empty. Multiple producers and consumers can use the queue. Please tell me if you see any problems.
Update: Edited as per answers 1)Resolved the issue of "Queue Full" situation. 2) There is BlockingCollection<T> and ConcurrentQueue<T> in .NET4. So there is no need to reinvent the wheel(for .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; } } }