/// <summary> /// Adds an object to the end of the queue. /// </summary> /// <param name="item">the object to add to the queue</param> public void Enqueue(T item) { SingleLinkNode <T> oldTail = null; var newNode = new SingleLinkNode <T> { Item = item }; var newNodeWasAdded = false; while (!newNodeWasAdded) { oldTail = _tail; var oldTailNext = oldTail.Next; if (_tail == oldTail) { if (oldTailNext == null) { newNodeWasAdded = Interlocked.CompareExchange(ref _tail.Next, newNode, null) == null; } else { Interlocked.CompareExchange(ref _tail, oldTailNext, oldTail); } } } Interlocked.CompareExchange(ref _tail, newNode, oldTail); Interlocked.Increment(ref _count); }
/// <summary> /// Clears the queue. /// </summary> /// <remarks>This method is not thread-safe.</remarks> public void Clear() { var currentNode = _head; while (currentNode != null) { var tempNode = currentNode; currentNode = currentNode.Next; tempNode.Item = default(T); tempNode.Next = null; } _head = new SingleLinkNode <T>(); _tail = _head; _count = 0; }
/// <summary> /// Removes and returns the object at the beginning of the queue. /// </summary> /// <param name="item"> /// when the method returns, contains the object removed from the beginning of the queue, /// if the queue is not empty; otherwise it is the default value for the element type /// </param> /// <returns> /// true if an object from removed from the beginning of the queue; /// false if the queue is empty /// </returns> public bool TryDequeue(out T item) { item = default(T); SingleLinkNode <T> oldHead = null; var haveAdvancedHead = false; while (!haveAdvancedHead) { oldHead = _head; var oldTail = _tail; var oldHeadNext = oldHead.Next; if (oldHead == _head) { if (oldHead == oldTail) { if (oldHeadNext == null) { return(false); } Interlocked.CompareExchange(ref _tail, oldHeadNext, oldTail); } else { item = oldHeadNext.Item; haveAdvancedHead = Interlocked.CompareExchange(ref _head, oldHeadNext, oldHead) == oldHead; } } } Interlocked.Decrement(ref _count); return(true); }
/// <summary> /// Default constructor. /// </summary> public LockFreeQueue() { _head = new SingleLinkNode <T>(); _tail = _head; }