講講Lock塊的含義

2021-06-03 17:27:27 字數 1407 閱讀 7087

lock 關鍵字可以用來確保**塊完成執行,而不會被

其他執行緒中斷。這是通過在**塊執行期間為給定物件獲取互斥鎖來實現的。

先來看看執行過程,**示例如下:

假設執行緒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(this) 可能會有問題,因為不受控制的**也可能會鎖定該物件。這可能導致死鎖,即兩個或更多個執行緒等待釋放同一物件。出於同樣的原因,鎖定公共資料型別(相比於物件)也可能導致問題。而且lock(this)只對當前物件有效,如果多個物件之間就達不到同步的效果。

lock(typeof(class))與鎖定字串一樣,範圍太廣了。

某些系統類提供專門用於鎖定的成員。例如,array 型別提供 syncroot。許多集合型別也提供 syncroot。

private static readonly object obj = new object();

為什麼要設定成唯讀的呢?這時因為如果在lock**段中改變obj的值,其它執行緒就暢通無阻了,因為互斥鎖的物件變了,object.referenceequals必然返回false。

C lock關鍵詞 lock語句塊 執行緒鎖

1.lock 關鍵字將語句塊標記為臨界區,方法是獲取給定物件的互斥鎖,執行語句,然後釋放該鎖。2.lock 語句塊鎖定,功能等同於 monitor.enter obj 段 monitor.exit obj 3.lock語句塊鎖定和monitor執行緒鎖,不能跨程序同步 二 備註 lock關鍵字可確保...

C lock關鍵詞 lock語句塊 執行緒鎖

1.lock 關鍵字將語句塊標記為臨界區,方法是獲取給定物件的互斥鎖,執行語句,然後釋放該鎖。2.lock 語句塊鎖定,功能等同於 monitor.enter obj 段 monitor.exit obj 3.lock語句塊鎖定和monitor執行緒鎖,不能跨程序同步 二 備註 lock關鍵字可確保...

講講MySQL的分割槽

分割槽劣勢 分割槽劣勢 隨著mysql越來越流行,mysql裡面的儲存的資料也越來越大。在日常的工作中,我們經常遇到一張表裡面儲存了上億甚至過十億的記錄。這些表裡面儲存了大量的歷史記錄。對於這些歷史資料的清理是乙個非常頭疼事情,由於所有的資料都乙個普通的表裡。所以只能是啟用乙個或多個帶where條件...