ZT:http://www.cnblogs.com/overred/archive/2009/09/30/Lock-Free-Stack.html
多线程下,无锁编程是种境界!其实Lock-Free或Lock-Low不单单是一种技术,而是一种思想。如前篇《High Performance Cacher》,里面使用“伪装双链表”,使锁尽量减少,从而提高性能。本文将使用CAS的原子访问方式实现一个Lock-Free Stack。何为CAS?通俗点就是先比较后交换,Interlocked.CompareExchange函数。何为原子访问?当一个线程访问一个资源的同时,保证其他线程不会在同一时刻访问同一资源,如Interlocked系列函数。.Net下BCL中的Interlocked系列函数是如何保证这一行为的呢?泛泛而谈,实现层还是调用硬件支持,最后到CPU层面的总线锁(具体可以参考Rotor实现,有空我单独开篇讲解)。Lock Free Stack代码:
public class LockFreeStack<T> : IEnumerable<T> { #region Fields private Node _nodeList; #endregion #region Methods public T Pop() { try { Node n; do { n = _nodeList; if (n == null) throw new ArgumentNullException("stack empty!"); } while (Interlocked.CompareExchange(ref _nodeList, n.Next, n) != n); return n.Value; } finally { Interlocked.Decrement(ref _count); } } public void Push(T value) { try { Node n = new Node(); n.Value = value; Node o; do { o = _nodeList; n.Next = o; } while (Interlocked.CompareExchange(ref _nodeList, n, o) != o); } finally { Interlocked.Increment(ref _count); } } public IEnumerator<T> GetEnumerator() { while (_nodeList != null) { yield return _nodeList.Value; _nodeList = _nodeList.Next; } } IEnumerator IEnumerable.GetEnumerator() { Interlocked.Exchange(ref _count, 0); return ((IEnumerable<T>)this).GetEnumerator(); } #endregion #region Attribute private long _count; public long Count { get { return Interlocked.Read(ref _count); } set { _count = value; } } #endregion private class Node { internal T Value; internal Node Next; } }