C#无锁队列的实现

using System.Threading;

namespace TestTask
{
    public class QueLockFree<T>
    {
        private class Node
        {
            internal readonly T Data;
            internal Node Next;

            public Node(T data)
            {
                this.Data = data;
                this.Next = null;
            }
        }

        private Node _head;
        private Node _tail;

        public QueLockFree()
        {
            _head = new Node(default(T));
            _tail = _head;
        }

        public bool IsEmpty
        {
            get { return (_head.Next == null); }
        }

        public void Enqueue(T item)
        {
            Node newNode = new Node(item);
            while (true)
            {
                Node curTail = _tail;
                Node next = curTail.Next;

                //判断_tail是否被其他process改变
                if (curTail == _tail)
                {
                    //A 有其他process执行C成功,_tail应该指向新的节点
                    if (next == null)
                    {
                        //public static int CompareExchange(ref int location1,int value,int comparand)
                        //比较location1与comparand,如果不相等,什么都不做;
                        //如果location1与comparand相等,则用value替换location1的值。
                        //无论比较结果相等与否,返回值都是location1中原有的值。
                        if (Interlocked.CompareExchange<Node>(ref curTail.Next, newNode, next) == next)
                        {
                            //D 尝试修改tail
                            Interlocked.CompareExchange<Node>(ref _tail, newNode, curTail);
                            return;
                        }
                    }
                    else
                    {
                        //B 帮助其他线程完成D操作
                        Interlocked.CompareExchange<Node>(ref _tail, next, curTail);
                    }
                }
            }
        }

        public bool TryDequeue(out T result)
        {
            while (true)
            {
                Node curHead = _head;
                Node curTail = _tail;
                Node next = curHead.Next;
                if (curHead == _head)
                {
                    if (next == null)  //Queue为空
                    {
                        result = default(T);
                        return false;
                    }
                    if (curHead == curTail) //Queue处于Enqueue第一个node的过程中
                    {
                        //尝试帮助其他Process完成操作
                        Interlocked.CompareExchange<Node>(ref _tail, next, curTail);
                    }
                    else
                    {
                        //取next.Item必须放到CAS之前
                        result = next.Data;
                        //如果_head没有发生改变,则将_head指向next并退出
                        if (Interlocked.CompareExchange<Node>(ref _head, next, curHead) == curHead)
                        {
                            break;
                        }
                    }
                }
            }

            return true;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/f110300641/article/details/88390452