一、lock關鍵詞說明
1. lock 關鍵字將語句塊標記為臨界區,方法是獲取給定對象的互斥鎖,執行語句,然后釋放該鎖。
2. lock 語句塊鎖定,功能等同於
Monitor.Enter(obj); //代碼段 Monitor.Exit(obj);
3. lock語句塊鎖定和Monitor線程鎖,不能跨進程同步
lock
關鍵字可確保當一個線程位於代碼的臨界區時,另一個線程不會進入該臨界區。 如果其他線程嘗試進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。
線程 這節討論了線程處理。
lock
關鍵字在塊的開始處調用 Enter,而在塊的結尾處調用 Exit。 ThreadInterruptedException 引發,如果 Interrupt 中斷等待輸入 lock
語句的線程。
通常,應避免鎖定 public
類型,否則實例將超出代碼的控制范圍。 常見的結構 lock (this)
、lock (typeof (MyType))
和 lock ("myLock")
違反此准則:
-
如果實例可以被公共訪問,將出現
lock (this)
問題。 -
如果
MyType
可以被公共訪問,將出現lock (typeof (MyType))
問題。 -
由於進程中使用同一字符串的任何其他代碼都將共享同一個鎖,所以出現
lock("myLock")
問題。
最佳做法是定義 private
對象來鎖定, 或 private static
對象變量來保護所有實例所共有的數據。
在 lock
語句的正文不能使用 等待 關鍵字。
三、特別說明
1.lock語句中鎖定的必須是引用類型的對象,不能是值類型
2.為了避免死鎖,lock的對象需要是private對象
3.為了避免lock對象的唯一性,通lock的對象為 private static或者 private readonly static
四、使用示例
private readonly static object _MyLock = new object(); //對於鎖推薦使用靜態私有靜態變量 //private readonly object _MyLock = new object(); /// <summary> /// 事務, 多表修改 /// </summary> /// <param name="name"></param> /// <returns></returns> public bool UpdateName(string name) { lock (_MyLock) { using (var tran = new TransactionScope()) { ModuleOperate _module = new ModuleOperate(); //1.修改模塊名稱 _module.UpdateFirstName("模塊:" + name); //2.修改菜單 this.UpdateFirstName("菜單:" + name); //提交事務 tran.Complete(); } } return true; }
更多文檔參考: