lock 語句(C# 參考)
阿新 • • 發佈:2019-01-07
lock
語句獲取給定物件的互斥 lock,執行語句 lock,然後釋放 lock。 持有 lock 時,持有 lock 的執行緒可以再次獲取並釋放 lock。 阻止任何其他執行緒獲取 lock 並等待釋放 lock。
lock
語句具有以下格式
C#
lock (x)
{
// Your code...
}
其中 x
是引用型別的表示式。 它完全等同於
C#
object __lockObj = x; bool __lockWasTaken = false; try { System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken); // Your code... } finally { if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj); }
由於該程式碼使用 try...finally 塊,即使在 lock
語句的正文中引發異常,也會釋放 lock。
在 lock
語句的正文中不能使用 await 關鍵字。
備註
當同步對共享資源的執行緒訪問時,請鎖定專用物件例項(例如,private readonly object balanceLock = new object();
)或另一個不太可能被程式碼無關部分用作 lock 物件的例項。 避免對不同的共享資源使用相同的 lock 物件例項,因為這可能導致死鎖或鎖爭用。 具體而言,應避免使用
用作 lock 物件。
示例
以下示例定義了一個 Account
類,該類通過鎖定專用的 balanceLock
例項來同步對其專用 balance
欄位的訪問。 使用相同的例項進行鎖定可確保嘗試同時呼叫 Debit
或 Credit
方法的兩個執行緒無法同時更新 balance
欄位。
C#
using System; using System.Threading.Tasks; public class Account { private readonly object balanceLock = new object(); private decimal balance; public Account(decimal initialBalance) { balance = initialBalance; } public decimal Debit(decimal amount) { lock (balanceLock) { if (balance >= amount) { Console.WriteLine($"Balance before debit :{balance, 5}"); Console.WriteLine($"Amount to remove :{amount, 5}"); balance = balance - amount; Console.WriteLine($"Balance after debit :{balance, 5}"); return amount; } else { return 0; } } } public void Credit(decimal amount) { lock (balanceLock) { Console.WriteLine($"Balance before credit:{balance, 5}"); Console.WriteLine($"Amount to add :{amount, 5}"); balance = balance + amount; Console.WriteLine($"Balance after credit :{balance, 5}"); } } } class AccountTest { static void Main() { var account = new Account(1000); var tasks = new Task[100]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Run(() => RandomlyUpdate(account)); } Task.WaitAll(tasks); } static void RandomlyUpdate(Account account) { var rnd = new Random(); for (int i = 0; i < 10; i++) { var amount = rnd.Next(1, 100); bool doCredit = rnd.NextDouble() < 0.5; if (doCredit) { account.Credit(amount); } else { account.Debit(amount); } } } }
C# 語言規範
有關詳細資訊,請參閱 C# 語言規範。 該語言規範是 C# 語法和用法的權威資料。