C 基礎 說說lock到底鎖誰?

2022-02-07 06:22:03 字數 2669 閱讀 7013

最近乙個月一直在弄檔案傳輸元件,其中用到多執行緒的技術,但有的地方確實需要只能有乙個執行緒來操作,如何才能保證只有乙個執行緒呢?首先想到的就是鎖的概念,最近在我們專案組中聽的最多的也是鎖誰,如何鎖?看到有同事使用lock(this),也有lock(private static object),那就有點困惑了,lock到底鎖誰才是最合適的呢?

首先先上官方msdn的說法

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 語句的正文不能使用 等待 關鍵字。

enter指的是monitor.enter(獲取指定物件上的排他鎖。),exit指的是monitor.exit(釋放指定物件上的排他鎖。)

有上面msdn的解釋及exit方法,可以這樣猜測「直到該物件被釋放」,」該物件「應該是指鎖的物件,物件釋放了或者物件改變了,其他的執行緒才可以進入**臨界區(是不是可以這樣來理解?)。

在多執行緒中,每個執行緒都有自己的資源,但是**區是共享的,即每個執行緒都可以執行相同的函式。這可能帶來的問題就是幾個執行緒同時執行乙個函式,導致資料的混亂,產生不可預料的結果,因此我們必須避免這種情況的發生。

打個比方,有這樣乙個情景,很多公司所在的大廈的廁所的蹲位都是小單間型的,也就是一次只能進去乙個人,那麼為了避免每次進去乙個人,那怎麼做呢?不就是乙個人進去之後順手把門鎖上麼?這樣你在裡面幹啥事,外邊的人也只能等待你解放完了,才能進入。而蹲位的資源(蹲位,手紙等)是共享的。

最常使用的鎖是如下格式的**段:

private

static

object objlock = new

object

();lock

(objlock )

為什麼鎖的物件是私有的呢?還是以廁所為例子吧,私有就好比,這把鎖只有你能訪問到,而且最好這把鎖不會因為外力而有所改變,別人訪問不到,這樣才能保證你進去了,別人就進不去了,如果是公有的,就好比你蹲位小單間的鎖不是安裝在裡面而是安裝在外邊的,別人想不想進就不是你所能控制的了,這樣也不安全。

原文章列舉的demo無法說明問題,已將原文章的demo刪除,將修改後的demo遷移到這篇文章。

[c#基礎]說說lock到底鎖誰?(補充與修改)

答案是否定的,如

當然lock(null)也是不行的,如圖

雖然編譯可以通過,但是執行就會出錯。

string也是應用型別,從語法上來說是沒有錯的。

但是鎖定字串尤其危險,因為字串被公共語言執行庫 (clr)「暫留」。 這意味著整個程式中任何給定字串都只有乙個例項,就是這同乙個物件表示了所有執行的應用程式域的所有執行緒中的該文字。因此,只要在應用程式程序中的任何位置處具有相同內容的字串上放置了鎖,就將鎖定應用程式中該字串的所有例項。通常,最好避免鎖定 public 型別或鎖定不受應用程式控制的物件例項。例如,如果該例項可以被公開訪問,則 lock(this) 可能會有問題,因為不受控制的**也可能會鎖定該物件。這可能導致死鎖,即兩個或更多個執行緒等待釋放同一物件。出於同樣的原因,鎖定公共資料型別(相比於物件)也可能導致問題。而且lock(this)只對當前物件有效,如果多個物件之間就達不到同步的效果。lock(typeof(class))與鎖定字串一樣,範圍太廣了。

關於lock的介紹就到這裡,有下面幾點需要注意的地方

1、lock的是引用型別的物件,string型別除外。

2、lock推薦的做法是使用靜態的、唯讀的、私有的物件。

3、保證lock的物件在外部無法修改才有意義,如果lock的物件在外部改變了,對其他執行緒就會暢通無阻,失去了lock的意義。

@aulan

this 表示的就是當前例項,當你再new乙個的時候,鎖定的就不再是同乙個物件了。 不能鎖定值型別的原因是,當這個值型別傳遞到另乙個執行緒的時候,會建立乙個副本,鎖定的也不再是同乙個物件了。 鎖定字串帶來的問題是,字串在clr中會暫存在 記憶體中,如果有兩個變數被分配了相同的字串內容,那麼這兩個引用會指向同一塊記憶體,實際鎖定也就是同乙個物件,這就會導致整個應用程式的阻塞。所以鎖定字串是非常危險的行為。

參考文章

C 說說lock到底鎖誰?(2)

今天在園子裡面有園友反饋關於 c 基礎 說說lock到底鎖誰?文章中lock this 的問題。後來針對文章中的例子,仔細想了一下,確實不準確,才有了這篇文章的補充,已經對文章中的demo進行修改。乙個例子 using system using system.collections.generic ...

說說lock到底鎖誰 I ?

最近乙個月一直在弄檔案傳輸元件,其中用到多執行緒的技術,但有的地方確實需要只能有乙個執行緒來操作,如何才能保證只有乙個執行緒呢?首先想到的就是鎖的概念,最近在我們專案組中聽的最多的也是鎖誰,如何鎖?看到有同事使用lock this 也有lock private static object 那就有點困...

Python基礎 多執行緒與Lock鎖

python的執行緒是真正的posix thread,而不是模擬出來的執行緒。python的標準庫提供了兩個模組 thread低階模組和threading高階模組 重點 執行示例 由於任何程序預設就會啟動乙個執行緒,我們把該執行緒稱為主線程,主線程又可以啟動新的執行緒,python的threadin...