Compare And Swap 比较并交换 硬件同步原语
.NET通过 System.Threading.Interlocked.CompareExchang重载实现CAS
自旋锁CAS实现
public class SpinLock { private volatile int locked; public void Aquire() { while (System.Threading.Interlocked.CompareExchange(ref locked, 1, 0) != 0)
{
//‘浪费’CPU周期 重试
} } public void Release() { locked = 0; }
因为自旋锁浪费CPU周期所以它不适合保护长时间的操作,如数据库访问,磁盘大文件写操作,网络发包等。
如果保护的代码很快执行完毕,自旋锁很有用了,如修改对象字段,增加变量值,向简单集合插入数据等。
public static void DoWithCAS<T>(ref T location, Func<T, T> generator) where T : class { T temp, replace; do { temp = location; replace = generator(temp); } while (Interlocked.CompareExchange(ref location, replace, temp) != temp); }
单向链表无锁栈实现:
public class LockFreeStack<T> { private class Node { public T Data; public Node Next; } private Node head; public void Push(T element) { Node node = new Node { Data = element }; DoWithCAS(ref head, h => { node.Next = h; return node; }); } public bool TryPop(out T element) { //DoWithCAS does not work here because we need early termination semantics Node node; do { node = head; if (node == null) { element = default(T); return false; //bail out – nothing to return } } while (Interlocked.CompareExchange(ref head, node.Next, node) != node); element = node.Data; return true; }