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

C# 多線程程式設計系列(五):Monitor 同步技術詳解——TryEnter 與鎖超時實戰

     編輯:關於C語言

Monitor 與 lock 的關係

Monitor 類別提供比 lock 更精細的控制。若僅需基本互斥,lock 足矣;但需鎖超時、非阻塞嘗試等進階功能時,Monitor 是最佳選擇。

TryEnter 基本語法與模式

if (Monitor.TryEnter(lockObj, 1000))
{
    try
    {
        // 臨界區程式碼
    }
    finally
    {
        Monitor.Exit(lockObj);
    }
}
else
{
    // 超時處理邏輯
}

設定 1 秒超時:若 1 秒內鎖被釋放則返回 true,否則返回 false 進入超時處理分支。

實戰:避免雙向死鎖的經典範例

class Program
{
    private static Object objA = new Object();
    private static Object objB = new Object();

    public static void LockA()
    {
        if (Monitor.TryEnter(objA, 1000))
        {
            Thread.Sleep(1000);
            if (Monitor.TryEnter(objB, 2000))
            {
                Monitor.Exit(objB);
            }
            else { Console.WriteLine("LockB timeout"); }
            Monitor.Exit(objA);
        }
        Console.WriteLine("LockA");
    }

    public static void LockB()
    {
        if (Monitor.TryEnter(objB, 2000))
        {
            Thread.Sleep(2000);
            if (Monitor.TryEnter(objA, 1000))
            {
                Monitor.Exit(objA);
            }
            else { Console.WriteLine("LockA timeout"); }
            Monitor.Exit(objB);
        }
        Console.WriteLine("LockB");
    }

    public static void Main()
    {
        Thread threadA = new Thread(LockA);
        Thread threadB = new Thread(LockB);
        threadA.Start();
        threadB.Start();
        Thread.Sleep(4000);
        Console.WriteLine("線程結束");
    }
}

設計精髓

  • 兩線程嘗試以相反順序獲取鎖(A→B vs B→A),極易死鎖
  • 引入差異化超時時間(1000ms vs 2000ms)打破對稱性
  • 超時即放棄已持有鎖,避免循環等待
  • finally 確保異常時也能釋放鎖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved