zoukankan      html  css  js  c++  java
  • C# LockFreeStack类

    单链表实现的LockFreeStack

    using System;
    using System.Collections;
    using System.Threading;

    namespace Rocky.Stored
    {
    public class LockFreeStack : IEnumerable
    {
    private class SingleLinkedNode
    {
    public object Value;
    public SingleLinkedNode Next;
    }

    private SingleLinkedNode m_head;
    private int count;

    public int Count
    {
    get { return count; }
    }

    public void Push(object item)
    {
    SingleLinkedNode node
    = new SingleLinkedNode();
    node.Value
    = item;
    SingleLinkedNode head;
    do
    {
    head
    = m_head;
    node.Next
    = head;
    }
    while (m_head != head || Interlocked.CompareExchange(ref m_head, node, head) != head);
    Interlocked.Increment(
    ref count);
    }

    public object Peek()
    {
    SingleLinkedNode head
    = m_head;
    if (head == null)
    {
    throw new InvalidOperationException("Stack Empty!");
    }
    return head.Value;
    }

    public object Pop()
    {
    object result;
    if (TryPop(out result))
    {
    return result;
    }
    throw new InvalidOperationException("Stack Empty!");
    }

    /// <summary>
    /// 考虑到在多线程环境中,这里不抛出异常。我们需要人为判断其是否为空,即 !TryPop() or result != null
    /// </summary>
    /// <returns></returns>
    public bool TryPop(out object item)
    {
    SingleLinkedNode head;
    SingleLinkedNode next;
    do
    {
    head
    = m_head;
    if (head == null)
    {
    item
    = null;
    return false;
    }
    next
    = m_head.Next;
    }
    while (Interlocked.CompareExchange(ref m_head, next, head) != head);
    Interlocked.Decrement(
    ref count);
    item
    = head.Value;
    return true;
    }

    public object SpinPop()
    {
    SingleLinkedNode head;
    SpinWait spin
    = new SpinWait();
    while (true)
    {
    SingleLinkedNode next;
    do
    {
    head
    = m_head;
    if (head == null)
    {
    goto emptySpin;
    }
    next
    = head.Next;
    }
    while (m_head != head || Interlocked.CompareExchange(ref m_head, next, head) != head);
    break;
    emptySpin:
    spin.Spin();
    }
    Interlocked.Decrement(
    ref count);
    return head.Value;
    }

    public bool Contains(object item)
    {
    SingleLinkedNode head
    = m_head;
    while (m_head != null && head != null)
    {
    if (head.Value.Equals(item))
    {
    return true;
    }
    head
    = head.Next;
    }
    return false;
    }

    public void Clear()
    {
    Interlocked.Exchange(
    ref m_head, null);
    Interlocked.Exchange(
    ref count, 0);
    }

    public IEnumerator GetEnumerator()
    {
    SingleLinkedNode head
    = m_head;
    while (m_head != null && head != null)
    {
    yield return head.Value;
    head
    = head.Next;
    }
    }
    }
    }
  • 相关阅读:
    SQL注入攻击
    新手指引,php什么是常量、变量、数组、类和对象及方法?
    JQuery坑,说说哪些大家都踩过的坑
    利用Jsonp实现跨域请求,spring MVC+JQuery
    【实用】需要收藏备用的JQuery代码片段
    【动画】JQuery实现冒泡排序算法动画演示
    【基础】26个命令玩转linux,菜鸟及面试必备
    【收藏】8段JQuery处理表单的代码片段,很实用
    【实用】Html5实现文件异步上传
    【基础】新手任务,五分钟全面掌握JQuery选择器
  • 原文地址:https://www.cnblogs.com/Googler/p/1754501.html
Copyright © 2011-2022 走看看