首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

多線程入門系列(七):Interlocked 原子操作與無鎖程式設計

     編輯:關於C#

Interlocked 核心價值

System.Threading.Interlocked 提供原子操作方法,在硬體層面保證操作不可分割,無需鎖即可實現線程安全的基本數值運算,效能遠優於鎖。

關鍵方法總覽

方法說明適用型別
Increment(ref int)原子遞增,返回新值int, long
Decrement(ref int)原子遞減,返回新值int, long
Add(ref int, int)原子加法,返回新值int, long
Exchange(ref T, T)原子交換,返回舊值int, long, float, double, object, pointer
CompareExchange(ref T, T, T)原子比較交換(CAS),返回舊值同上
Read(ref long)原子讀取 64 位整數(32 位系統需此方法)long

基本計數器範例

using System;
using System.Threading;

class CounterDemo
{
    static int count = 0;
    
    static void Main()
    {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++)
        {
            threads[i] = new Thread(IncrementCount);
            threads[i].Start();
        }
        
        foreach (var t in threads) t.Join();
        Console.WriteLine("最終計數: {0} (預期 100000)", count);
    }
    
    static void IncrementCount()
    {
        for (int i = 0; i < 10000; i++)
        {
            Interlocked.Increment(ref count);
            // 等同於:Interlocked.Add(ref count, 1);
        }
    }
}

CAS 模式實作無鎖堆疊

using System;
using System.Threading;

public class LockFreeStack<T>
{
    private sealed class Node
    {
        public T Value;
        public Node Next;
        public Node(T value) { Value = value; }
    }
    
    private Node head = null;
    
    public void Push(T item)
    {
        Node newNode = new Node(item);
        Node oldHead;
        do
        {
            oldHead = head;
            newNode.Next = oldHead;
        } while (Interlocked.CompareExchange(ref head, newNode, oldHead) != oldHead);
    }
    
    public bool TryPop(out T item)
    {
        Node oldHead;
        do
        {
            oldHead = head;
            if (oldHead == null)
            {
                item = default(T);
                return false;
            }
        } while (Interlocked.CompareExchange(ref head, oldHead.Next, oldHead) != oldHead);
        
        item = oldHead.Value;
        return true;
    }
}

Interlocked vs lock 效能對比

// 簡單計數:Interlocked 勝出(無核心轉換、無上下文切換)
// 複雜邏輯/多變數:需用 lock 或 Monitor
// 64 位讀寫在 32 位系統:必須用 Interlocked.Read/Exchange

注意事項

  • 僅適用於單一變數的簡單操作,複雜不變條件仍需鎖。
  • CompareExchange 是無鎖演算法核心(CAS),理解其語意至關重要。
  • 避免在迴圈中過度自旋(Spin),高爭用時考慮 Thread.SpinWait 或改用鎖。
  • .NET 4.6+ 提供 Volatile 類別配合記憶體屏障,更精細控制可見性。

圖示說明

(原文包含三張圖片,展示 Interlocked 方法結構、CAS 運作流程、無鎖堆疊示意)

Interlocked 方法總覽 CAS 比較交換流程 無鎖堆疊結構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved