亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

[C#基礎]說說lock到底鎖誰?

2019-11-17 02:39:16
字體:
來源:轉載
供稿:網友

[C#基礎]說說lock到底鎖誰?

寫在前面

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

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 ){    //要執行的代碼邏輯}

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

lock(this)

通過字面的意思就是鎖的當前實例對象。那是否對其他實例對象產生影響?那下面看一個例子:

 1 namespace Wolfy.LockDemo 2 { 3     class Program 4     { 5         static void Main(string[] args) 6         { 7             Test t = new Test(); 8             Test t2 = new Test(); 9             Thread[] threads = new Thread[10];10             for (int i = 0; i < threads.Length; i++)11             {12                 //通過循環創建10個線程。13                 threads[i] = new Thread(() =>14                 {15                     t2.Print();16                 });17                 //為每個線程設置一個名字18                 threads[i].Name = "thread" + i;19 20             }21             //開啟創建的十個線程22             for (int i = 0; i < threads.Length; i++)23             {24                 threads[i].Start();25             }26 27             Console.Read();28         }29     }30     class Test31     {32         public void Print()33         {34             lock (this)35             {36                 for (int i = 0; i < 5; i++)37                 {38                     Console.WriteLine("/t" + Thread.CurrentThread.Name.ToString() + "/t" + i.ToString() + " ");39                 }40             }41         }42     }43 }

如果在不加鎖的情況下輸出如下:

從上面的輸出結果也可以看出,線程出現了爭搶的現象,而這并不是我們想要的結果,我們想要的是,每次只有一個線程去執行Print方法。那我們就嘗試一下lock(this)

 1     class Test 2     { 3         public void Print() 4         { 5             lock (this) 6             { 7                 for (int i = 0; i < 5; i++) 8                 { 9                     Console.WriteLine("/t" + Thread.CurrentThread.Name.ToString() + "/t" + i.ToString() + " ");10                 }11             }12         }13     }

輸出結果

從輸出結果,覺得大功告成了,可是現在情況又來了,在項目中的其他的地方,有同事也這樣寫了這樣的代碼,又創建了一個Test對象,而且他也知道使用多線程執行耗時的工作,那么就會出現類似下面的代碼。

 1 namespace Wolfy.LockDemo 2 { 3     class Program 4     { 5         static void Main(string[] args) 6         { 7             Test t = new Test(); 8             Test t2 = new Test(); 9             t2.Age = 20;10             Thread[] threads = new Thread[10];11             for (int i = 0; i < threads.Length; i++)12             {13                 //通過循環創建10個線程。14                 threads[i] = new Thread(() =>15                 {16                     t.Print();17                     t2.Print();18                 });19                 //為每個線程設置一個名字20                 threads[i].Name = "thread" + i;21 22             }23 24 25             //開啟創建的十個線程26             for (int i = 0; i < threads.Length; i++)27             {28                 threads[i].Start();29             }30 31             Console.Read();32         }33     }34     class Test35     {36         public int Age { get; set; }37         public void Print()38         {39             lock (this)40             {41                 for (int i = 0; i < 5; i++)42                 {43                     Console.WriteLine("/t" + Thread.CurrentThread.Name.ToString() + "/t" + i.ToString() + " ");44                 }45             }46         }47     }48 }

這里為Test加了一個Age屬性,為了區別當前創建的對象不是同一個對象。

輸出的結果為

在輸出的結果中已經出現了線程搶占執行的情況了,而不是一個線程執行完另一個線程在執行。

lock(private obj)

那么我們現在使用一個全局的私有的對象試一試。

 1 namespace Wolfy.LockDemo 2 { 3     class Program 4     { 5         private static object objLock = new object(); 6         static void Main(string[] args) 7         { 8             Test t = new Test(); 9             Test t2 = new Test();10             t2.Age = 20;11             Thread[] threads = new Thread[10];12             for (int i = 0; i < threads.Length; i++)13             {14                 //通過循環創建10個線程。15                 threads[i] = new Thread(() =>16                 {17                     lock (objLock)18                     {19                         t.Print();20                         t2.Print();21                     }22                 });23                 //為每個線程設置一個名字24                 threads[i].Name = "thread" + i;25 26             }27 28 29             //開啟創建的十個線程30             for (int i = 0; i < threads.Length; i++)31             {32                 threads[i].Start();33             }34 35             Console.Read();36         }37     }38     class Test39     {40         public int Age { get; set; }41         public void Print()42         {43             for (int i = 0; i < 5; i++)44             {45                 Console.WriteLine("/t" + Thread.CurrentThread.Name.ToString() + "/t" + i.ToString() + " ");46             }47         }48     }49 }

輸出的結果

從輸出的結果也可以看出,有序的,每次進來一個線程執行。

那通過上面的比較可以有這樣的一個結論,lock的結果好不好,還是關鍵看鎖的誰,如果外邊能對這個誰進行修改,lock就失去了作用。所以一般情況下,使用靜態的并且是只讀的對象。

也就有了類似下面的代碼

1  private static readonly object objLock = new object();

你可能會說,不對啊,你下面的代碼跟上面的代碼不一樣啊,為什么就得出這樣的結論?難道就不能把Object放在test類中么,放在test類中的話,在new Test()的時候,其實放在Test中也是可以的,只要保證objLock在外部是無法修改的就可以。

上面說的最多的是lock對象,那么它能不能lock值類型?

答案是否定的,如

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

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

lock(string)

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

但是鎖定字符串尤其危險,因為字符串被公共語言運行庫 (CLR)“暫留”。 這意味著整個程序中任何給定字符串都只有一個實例,就是這同一個對象表示了所有運行的應用程序域的所有線程中的該文本。因此,只要在應用程序進程中的任何位置處具有相同內容的字符串上放置了鎖,就將鎖定應用程序中該字符串的所有實例。通常,最好避免鎖定 public 類型或鎖定不受應用程序控制的對象實例。例如,如果該實例可以被公

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久亚洲精品一区| 国内揄拍国内精品少妇国语| 精品久久久久久久久久久久久久| 国产成人精品国内自产拍免费看| 成人午夜激情网| 欧美在线精品免播放器视频| 国产精品一区二区三区在线播放| 成人午夜在线观看| 国产精品稀缺呦系列在线| 国产啪精品视频| 久久男人资源视频| 韩剧1988在线观看免费完整版| 欧美性xxxx极品hd满灌| 欧美高跟鞋交xxxxhd| 在线观看欧美日韩| 日韩美女在线看| 欧美人与性动交a欧美精品| 日韩成人中文字幕在线观看| 亚洲精品美女在线观看| 欧美日韩国产一中文字不卡| 亚洲欧美中文在线视频| 亚洲影院色在线观看免费| 欧美日韩亚洲一区二区| 热门国产精品亚洲第一区在线| 亚洲最新中文字幕| 精品久久久久久中文字幕一区奶水| 97精品国产97久久久久久春色| 欧美一级黄色网| 91精品在线国产| 成人网中文字幕| 亚洲欧洲日产国码av系列天堂| 国产精品无码专区在线观看| 欧美激情亚洲另类| 亚洲福利在线观看| 在线看国产精品| 亚洲女人天堂色在线7777| 中文字幕不卡在线视频极品| 成人av在线亚洲| 九九视频直播综合网| 国产精品美女视频网站| 九九精品视频在线| 亚洲福利视频免费观看| 亚洲精品久久久久中文字幕欢迎你| 久久伊人91精品综合网站| 97在线视频免费看| 久久夜色精品亚洲噜噜国产mv| 日产精品久久久一区二区福利| 欧美成人午夜激情视频| 久久久综合av| 久久精品夜夜夜夜夜久久| 亚洲综合在线播放| 国产精品成人免费视频| 91亚洲精华国产精华| 国产91九色视频| 亚洲电影免费观看高清完整版在线| 成人天堂噜噜噜| 成人国产精品日本在线| 久久久日本电影| 成人激情在线播放| 国产精品一区av| 亚洲国产精品免费| 精品欧美一区二区三区| 另类图片亚洲另类| 亚洲国产成人久久综合| 福利视频第一区| 亚洲精选中文字幕| 日本久久久久久久久| 欧美激情a∨在线视频播放| 亚洲女同精品视频| 九九热99久久久国产盗摄| 午夜伦理精品一区| 一区二区三区回区在观看免费视频| 国产不卡一区二区在线播放| 亚洲欧美中文日韩v在线观看| 亚洲一级免费视频| 日韩在线观看精品| 日韩免费av一区二区| 国产精品爽爽爽爽爽爽在线观看| 日韩av网站大全| 欧美激情久久久久| 久久久精品中文字幕| 日本免费一区二区三区视频观看| 中文在线不卡视频| 久久久亚洲国产| 国产精品国产亚洲伊人久久| 国产精品99蜜臀久久不卡二区| 久久精品视频99| 欧美精品在线免费| 国产精品白嫩美女在线观看| 成人女保姆的销魂服务| 97精品国产91久久久久久| 欧美午夜片在线免费观看| 日韩在线观看高清| 久久免费视频观看| 欧美视频一二三| 欧洲亚洲在线视频| 亚洲精品国产品国语在线| 午夜精品一区二区三区在线播放| 91国产视频在线播放| 亚洲va男人天堂| 97久久国产精品| 日韩成人激情视频| 激情亚洲一区二区三区四区| 91夜夜未满十八勿入爽爽影院| 日韩资源在线观看| 久久久久久午夜| 欧美激情亚洲自拍| 久久亚洲国产精品成人av秋霞| 亚洲变态欧美另类捆绑| 菠萝蜜影院一区二区免费| 午夜精品三级视频福利| 欧美夜福利tv在线| 欧美激情女人20p| 亚洲欧洲日韩国产| 国产精品中文久久久久久久| 亚洲自拍偷拍第一页| 成人免费网视频| 久久手机免费视频| 日韩中文在线视频| 亚洲精品中文字| 中文日韩电影网站| 国产精品美女999| 日韩视频永久免费观看| 欧美极品少妇全裸体| 青草热久免费精品视频| 国产欧美在线视频| 九色91av视频| 日韩中文字幕在线免费观看| 国产精品丝袜久久久久久高清| 在线观看成人黄色| 亚洲人成在线免费观看| 国产精品免费观看在线| 在线精品高清中文字幕| 欧美中文在线视频| 久久久久久久久久久久av| 中文字幕精品一区久久久久| 好吊成人免视频| 精品偷拍一区二区三区在线看| 在线播放国产精品| 国产精品v片在线观看不卡| 国产精品成人免费电影| 91九色综合久久| 国产精品久在线观看| 欧美大片在线免费观看| 欧美日韩激情美女| 欧美亚洲成人xxx| 92看片淫黄大片看国产片| 欧美成人一二三| 最近中文字幕日韩精品| 日韩成人av在线| 日韩日本欧美亚洲| 高清欧美电影在线| 成年无码av片在线| 欧美精品www在线观看| 欧美性猛交xxxx富婆| 欧美亚洲伦理www| 久久久久久噜噜噜久久久精品| 国产精品自拍小视频| 国产婷婷97碰碰久久人人蜜臀| 国产精品老女人精品视频| 中文字幕日韩电影| 国产成人一区二区三区电影| 性日韩欧美在线视频| 欧美一级电影免费在线观看|