lock 關鍵字可以用來確保**塊完成執行,而不會被其他執行緒中斷。這是通過在**塊執行期間為給定物件獲取互斥鎖來實現的。
先來看看執行過程,**示例如下:
lock 語句用於獲取某個給定物件的互斥鎖,執行乙個語句,然後釋放該鎖。
lock-statement:(lock 語句:)
複製** **如下:
lock(expression) embedded-statement(lock ( 表示式 ) 嵌入語句)
lock 語句的表示式必須表示乙個引用型別的值。永遠不會為 lock 語句中的表示式執行隱式裝箱轉換,因此,如果該表示式表示的是乙個值型別的值,則會導致乙個編譯時錯誤。
下列形式的 lock 語句:
複製** **如下:
lock (x) ...
(其中 x 是乙個引用型別的表示式)完全等效於
複製** **如下www.cppcns.com:
system.threading.monitor.enter(x);
try
finally
不同的只是:實際執行中 x 只計算一次。
當乙個互斥鎖已被占用時,在同一執行緒中執行的**仍可以獲取和釋放該鎖。但是,在其他執行緒中執行的**在該鎖被釋放前是無法獲得它的。
乙個類程式設計客棧的 system.type 物件可以方便地用來當作關於該類的靜態方法的互斥鎖。例如:
複製** **如下:
class cache
}public static void remove(object x)
}}假設線www.cppcns.com程a先執行,執行緒b稍微慢一點。執行緒a執行到lock語句,判斷obj是否已申請了互斥鎖,判斷依據是逐個與已存在的鎖進行object.referenceequals比較(此處未加證實),如果不存在,則申請乙個新的互斥鎖,這時執行緒a進入lock裡面了。
這時假設執行緒b啟動了,而執行緒a還未執行完lock裡面的**。執行緒b執行到lock語句,檢查到obj已經申請了互斥鎖,於是等待;直到執行緒a執行完畢,釋放互斥鎖,執行緒b才能申請新的互斥鎖並執行lock裡面的**。
接下來說一些該lock什麼物件。
為什麼不能lock值型別,比如lock(1)呢?lock本質上monitor.enter,monitor.enter會使值型別裝箱,每次lock的是裝箱後的物件。lock其實是類似編譯器的語法糖,因此編譯器直接限制住不能lock值型別。
退一萬步說,就算能編譯器允許你lock(1),但是object.referenceequals(1,1)始終返回false(因為每次裝箱後都是不同物件),也就是說每次都會判斷成未申請互斥鎖,這樣在同一時間,別的執行緒照樣能夠訪問裡面的**,達不到同步的效果。同理lock((object)1)也不行。
那麼lock("***")字串呢?msdn上的原話是:
鎖定字串尤其危險,因為字串被公共語言執行庫 (clr)「暫留」。 這意味著整個程式中任何給定字串都只有乙個例項,就是這同乙個物件表示了所有執行的應用程式域的所有執行緒中的該文字。因此,只要在應用程式程序中的任何位置處具有相同內容的字串上放置了鎖,就將鎖定應用程式中該字串的所有例項。
通常,最好避免鎖定 public 型別或鎖定不受應用程式控制的物件例項。例如,如果該例項可以被公開訪問,則 lock 可能會有問題,因為不受控制的**也可能會鎖定該物件。這可能導致死鎖,即兩個或更多個執行緒等待釋放同一物件。出於同樣的原因,鎖定公共資料型別(相比於物件)也可能導致問題。而且lock(this)只對當前物件有效,如果多個物件之間就達不到同步的效果。
lock(typeof(class))與鎖定字串一樣,範圍太廣了。
某些系統類提供專門用於鎖定的成員。例如,array 型別提供 syncroot。許多集合型別也提供 syncroot。
而自定義類推薦用私有的唯讀靜態物件,比如:
複製** **如下:
private static readonly object obj = new object();
為什麼要設定成唯讀的呢?這時因為如果在lock**段中改變obj的值,其它執行緒就暢通無阻了,因為互斥鎖的
物件變了,object.referenceequals必然返回false。
本文標題: c#中lock用法詳解
本文位址:
C 多執行緒中 lock用法
本文介紹c lockkeyword,c 提供了乙個keywordlock,它能夠把一段 定義為相互排斥段 critical section 相互排斥段在乙個時刻內僅僅同意乙個執行緒進入執行,而其他執行緒必須等待。每個執行緒都有自己的資源,可是 區是共享的,即每個執行緒都能夠執行相同的函式。這可能帶來...
C 多執行緒中lock的用法
最近在看些c 的 發現很多是以前沒有接觸到了,只能上網查,把比較好的整理下來。經常碰到同時需要對某個資料進行操作,或者對某個檔案進行讀寫操作,對於這些操作我們以前往往不能很好的進行處理,自從c 語言中引入了lock這個關鍵字,以上問題就比較容易予以解決了,下面就是一段簡單的 public class...
C 中var用法詳解
一 歷史 從visual c 3.0 開始引進的。二 基本概念 l implicitly type 隱式型別 由編譯器在編譯時候根據初試值決定具體型別。是強型別的。三 使用限制 1.只能用於區域性變數,如 方法內,屬性範圍內,using 語句內部。不能用於類欄位,方法返回值和形參。class thi...