共用方式為


lock 陳述式 (C# 參考)

lock 關鍵字可將陳述式區塊標記為關鍵區段 (Critical Section),其做法是為指定的物件取得互斥鎖定、執行陳述式,接著釋出該鎖定。 下列範例包含一個 lock 陳述式。

    class Account
    {
        decimal balance;
        private Object thisLock = new Object();

        public void Withdraw(decimal amount)
        {
            lock (thisLock)
            {
                if (amount > balance)
                {
                    throw new Exception("Insufficient funds");
                }
                balance -= amount;
            }
        }
    }

如需詳細資訊,請參閱 執行緒同步處理 (C# 和 Visual Basic)

備註

lock 關鍵字可保證有執行緒在關鍵區段時,絕對不會有任何其他執行緒同時也進入這個關鍵區段執行。 如果其他執行緒嘗試進入已鎖定的程式碼,它將會等候、封鎖,直到該物件被釋出。

執行緒 (C# 和 Visual Basic) 這一章節會討論執行緒的處理。

lock 關鍵字會在區塊開始執行時呼叫 Enter,並在區塊結束時呼叫 ExitThreadInterruptedException 擲回,如果 Interrupt 中斷等待進入 lock 陳述式的執行緒。

一般而言,請避免鎖定 public 型別或程式碼無法控制的執行個體。 有三種常見的建構,分別為 lock (this)、lock (typeof (MyType)) 和 lock ("myLock"),違反這項方針:

  • lock (this) 在可公開存取執行個體的情況下,會是問題所在。

  • lock (typeof (MyType)) 在可公開存取 MyType 的情況下,會是問題所在。

  • lock("myLock") 會是問題所在,因為使用相同字串的處理序中若有任何其他程式碼,將會共用相同的鎖定。

最佳作法是定義要鎖定的 private 物件,或者定義 private static 物件變數保護所有執行個體通用的資料。

您可以在 lock 陳述式的主體中不能使用 等候 關鍵字。

範例

以下的範例顯示在 C# 中執行緒 (但不用鎖定) 的簡易用法。

    //using System.Threading; 

    class ThreadTest
    {
        public void RunMe()
        {
            Console.WriteLine("RunMe called");
        }

        static void Main()
        {
            ThreadTest b = new ThreadTest();
            Thread t = new Thread(b.RunMe);
            t.Start();
        }
    }
    // Output: RunMe called

下列範例使用到執行緒與 lock。 只要 lock 陳述式存在,此陳述式區塊就是關鍵區段,而且 balance 永遠不會成為負數。

    // using System.Threading; 

    class Account
    {
        private Object thisLock = new Object();
        int balance;

        Random r = new Random();

        public Account(int initial)
        {
            balance = initial;
        }

        int Withdraw(int amount)
        {

            // This condition never is true unless the lock statement 
            // is commented out. 
            if (balance < 0)
            {
                throw new Exception("Negative Balance");
            }

            // Comment out the next line to see the effect of leaving out  
            // the lock keyword. 
            lock (thisLock)
            {
                if (balance >= amount)
                {
                    Console.WriteLine("Balance before Withdrawal :  " + balance);
                    Console.WriteLine("Amount to Withdraw        : -" + amount);
                    balance = balance - amount;
                    Console.WriteLine("Balance after Withdrawal  :  " + balance);
                    return amount;
                }
                else
                {
                    return 0; // transaction rejected
                }
            }
        }

        public void DoTransactions()
        {
            for (int i = 0; i < 100; i++)
            {
                Withdraw(r.Next(1, 100));
            }
        }
    }

    class Test
    {
        static void Main()
        {
            Thread[] threads = new Thread[10];
            Account acc = new Account(1000);
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(new ThreadStart(acc.DoTransactions));
                threads[i] = t;
            }
            for (int i = 0; i < 10; i++)
            {
                threads[i].Start();
            }
        }
    }

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。語言規格是 C# 語法及用法的限定來源。

請參閱

參考

C# 關鍵字

陳述式關鍵字 (C# 參考)

MethodImplAttributes

Mutex

執行緒同步處理 (C# 和 Visual Basic)

概念

C# 程式設計手冊

監視器

Interlocked 作業

AutoResetEvent

其他資源

C# 參考

執行緒 (C# 和 Visual Basic)