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 Server textcopy 的使用
    看来,我还是不适合犯罪
    Oracle 游标范例
    嵌入式学习方法 关于ARM+linux(转)
    存储控制器与外设之间的关系 (SDRAM与BANK6连接概述)
    socket和多线程可移植性编程基础(转)
    Linux设备驱动开发环境的搭建(转)
    Android JNI知识简介
    Linux USB驱动框架分析
    LINUX系统中动态链接库的创建和使用
  • 原文地址:https://www.cnblogs.com/Googler/p/1754501.html
Copyright © 2011-2022 走看看