ConcurrentQueue<T>.Enqueue(T) Method是不是也是线程安全的?

eakey 2019-05-08 01:03:42
ConcurrentQueue<T>.TryDequeue(T) Method在MSDN中有提到是线程安全的,那
ConcurrentQueue<T>.Enqueue(T) Method是不是也是线程安全的,在MSDN文档中并无提到,知道的讲讲。
...全文
60 点赞 收藏 9
写回复
9 条回复
eakey 2019年05月11日
谢谢
引用 8 楼 正怒月神 的回复:
[quote=引用 6 楼 eakey 的回复:] [quote=引用 3 楼 正怒月神 的回复:] 2楼正解
public void Enqueue(T item)
        {
            SpinWait spin = new SpinWait();
            while (true)
            {
                Segment tail = m_tail;
                if (tail.TryAppend(item))
                    return;
                spin.SpinOnce();
            }
        }
public bool TryDequeue(out T result)
        {
            while (!IsEmpty)
            {
                Segment head = m_head;
                if (head.TryRemove(out result))
                    return true;
                //since method IsEmpty spins, we don't need to spin in the while loop
            }
            result = default(T);
            return false;
        }
看到代码,有点奇怪,微软为什么在Enqueue方法中要用 Segment tail = m_tail; if (tail.TryAppend(item)) 而不直接if (m_tail.TryAppend(item)),这有什么特殊意义吗?[/quote] 不清楚具体原因,可能是他们的规范导致的?[/quote]
回复 点赞
正怒月神 2019年05月08日
引用 6 楼 eakey 的回复:
[quote=引用 3 楼 正怒月神 的回复:] 2楼正解
public void Enqueue(T item)
        {
            SpinWait spin = new SpinWait();
            while (true)
            {
                Segment tail = m_tail;
                if (tail.TryAppend(item))
                    return;
                spin.SpinOnce();
            }
        }
public bool TryDequeue(out T result)
        {
            while (!IsEmpty)
            {
                Segment head = m_head;
                if (head.TryRemove(out result))
                    return true;
                //since method IsEmpty spins, we don't need to spin in the while loop
            }
            result = default(T);
            return false;
        }
看到代码,有点奇怪,微软为什么在Enqueue方法中要用 Segment tail = m_tail; if (tail.TryAppend(item)) 而不直接if (m_tail.TryAppend(item)),这有什么特殊意义吗?[/quote] 不清楚具体原因,可能是他们的规范导致的?
回复 点赞
stherix 2019年05月08日
引用 6 楼 eakey 的回复:
[quote=引用 3 楼 正怒月神 的回复:] 2楼正解
public void Enqueue(T item)
        {
            SpinWait spin = new SpinWait();
            while (true)
            {
                Segment tail = m_tail;
                if (tail.TryAppend(item))
                    return;
                spin.SpinOnce();
            }
        }
public bool TryDequeue(out T result)
        {
            while (!IsEmpty)
            {
                Segment head = m_head;
                if (head.TryRemove(out result))
                    return true;
                //since method IsEmpty spins, we don't need to spin in the while loop
            }
            result = default(T);
            return false;
        }
看到代码,有点奇怪,微软为什么在Enqueue方法中要用 Segment tail = m_tail; if (tail.TryAppend(item)) 而不直接if (m_tail.TryAppend(item)),这有什么特殊意义吗?[/quote]这个没区别,release模式编译应该是优化成一样的
回复 点赞
eakey 2019年05月08日
引用 3 楼 正怒月神 的回复:
2楼正解
public void Enqueue(T item)
        {
            SpinWait spin = new SpinWait();
            while (true)
            {
                Segment tail = m_tail;
                if (tail.TryAppend(item))
                    return;
                spin.SpinOnce();
            }
        }
public bool TryDequeue(out T result)
        {
            while (!IsEmpty)
            {
                Segment head = m_head;
                if (head.TryRemove(out result))
                    return true;
                //since method IsEmpty spins, we don't need to spin in the while loop
            }
            result = default(T);
            return false;
        }
看到代码,有点奇怪,微软为什么在Enqueue方法中要用 Segment tail = m_tail; if (tail.TryAppend(item)) 而不直接if (m_tail.TryAppend(item)),这有什么特殊意义吗?
回复 点赞
物联网_咸鱼 2019年05月08日
ConcurrentQueue本身就是线程安全的队列
回复 点赞
wanghui0380 2019年05月08日
引用 2 楼 娃都会打酱油了 的回复:
Enqueue就是一直在尝试TryAdd,直到成功为止
其实这就是上次有位老兄一直纠结的 “用个队列,可以多线程添加,一个移除,不用另外一个线程监控是否为空”的正解,上次已经告诉了他ConcurrentXXXX都可以的,但是他一直就纠结要自己做。 其实自己做也没问题,微软的代码就是例子,一个同步阻塞+自旋(为空就自己自旋)
回复 点赞
正怒月神 2019年05月08日
2楼正解
public void Enqueue(T item)
        {
            SpinWait spin = new SpinWait();
            while (true)
            {
                Segment tail = m_tail;
                if (tail.TryAppend(item))
                    return;
                spin.SpinOnce();
            }
        }
public bool TryDequeue(out T result)
        {
            while (!IsEmpty)
            {
                Segment head = m_head;
                if (head.TryRemove(out result))
                    return true;
                //since method IsEmpty spins, we don't need to spin in the while loop
            }
            result = default(T);
            return false;
        }
回复 点赞
娃都会打酱油了 2019年05月08日
Enqueue就是一直在尝试TryAdd,直到成功为止
回复 点赞
发动态
发帖子
C#
创建于2007-09-28

8.4w+

社区成员

64.0w+

社区内容

.NET技术 C#
社区公告
暂无公告