自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

解決C# lock this問題

開發(fā) 后端
本文介紹C# lock this問題,以及解決方法,介紹其中Interlocked類是專門為多個線程共享的變量提供原子操作。

在以前編程中遇到lock問題總是使用lock(this)一鎖了之,出問題后翻看MSDN突然發(fā)現(xiàn)下面幾行字:通常,應(yīng)避免鎖定 public 類型,否則實(shí)例將超出代碼的控制范圍。常見的結(jié)構(gòu) lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 違反此準(zhǔn)則:如果實(shí)例可以被公共訪問,將出現(xiàn)C# lock this問題。如果 MyType 可以被公共訪問,將出現(xiàn) lock (typeof (MyType)) 問題。由于進(jìn)程中使用同一字符串的任何其他代碼將共享同一個鎖,所以出現(xiàn) lock(“myLock”) 問題。來看看C# lock this問題:如果有一個類Class1,該類有一個方法用lock(this)來實(shí)現(xiàn)互斥:

  1. publicvoidMethod2()  
  2. {  
  3. lock(this)  
  4. {  
  5. System.Windows.Forms.MessageBox.Show("Method2End");  
  6. }  

如果在同一個Class1的實(shí)例中,該Method2能夠互斥的執(zhí)行。但是如果是2個Class1的實(shí)例分別來執(zhí)行Method2,是沒有互斥效果的。因?yàn)檫@里的lock,只是對當(dāng)前的實(shí)例對象進(jìn)行了加鎖。

Lock(typeof(MyType))鎖定住的對象范圍更為廣泛,由于一個類的所有實(shí)例都只有一個類型對象(該對象是typeof的返回結(jié)果),鎖定它,就鎖定了該對象的所有實(shí)例,微軟現(xiàn)在建議,不要使用lock(typeof(MyType)),因?yàn)殒i定類型對象是個很緩慢的過程,并且類中的其他線程、甚至在同一個應(yīng)用程序域中運(yùn)行的其他程序都可以訪問該類型對象,因此,它們就有可能代替您鎖定類型對象,完全阻止您的執(zhí)行,從而導(dǎo)致你自己的代碼的掛起。

鎖住一個字符串更為神奇,只要字符串內(nèi)容相同,就能引起程序掛起。原因是在.NET中,字符串會被暫時存放,如果兩個變量的字符串內(nèi)容相同的話,.NET會把暫存的字符串對象分配給該變量。所以如果有兩個地方都在使用lock(“my lock”)的話,它們實(shí)際鎖住的是同一個對象。到此,微軟給出了個lock的建議用法:鎖定一個私有的static 成員變量。

.NET在一些集合類中(比如ArrayList,HashTable,Queue,Stack)已經(jīng)提供了一個供lock使用的對象SyncRoot,用Reflector工具查看了SyncRoot屬性的代碼,在Array中,該屬性只有一句話:return this,這樣和lock array的當(dāng)前實(shí)例是一樣的。ArrayList中的SyncRoot有所不同

  1. get  
  2. {  
  3. if(this._syncRoot==null)  
  4. {  
  5. Interlocked.CompareExchange(refthis._syncRoot,newobject(),null);  
  6. }  
  7. returnthis._syncRoot; 

其中Interlocked類是專門為多個線程共享的變量提供原子操作(如果你想鎖定的對象是基本數(shù)據(jù)類型,那么請使用這個類),CompareExchange方法將當(dāng)前syncRoot和null做比較,如果相等,就替換成new object(),這樣做是為了保證多個線程在使用syncRoot時是線程安全的。集合類中還有一個方法是和同步相關(guān)的:Synchronized,該方法返回一個對應(yīng)的集合類的wrapper類,該類是線程安全的,因?yàn)樗拇蟛糠址椒ǘ加胠ock來進(jìn)行了同步處理,比如Add方法:

  1. publicoverridevoidAdd(objectkey,objectvalue)  
  2. {  
  3. lock(this._table.SyncRoot)  
  4. {  
  5. this._table.Add(key,value);  
  6. }  

這里要特別注意的是MSDN提到:從頭到尾對一個集合進(jìn)行枚舉本質(zhì)上并不是一個線程安全的過程。即使一個集合已進(jìn)行同步,其他線程仍可以修改該集合,這將導(dǎo)致枚舉數(shù)引發(fā)異常。若要在枚舉過程中保證線程安全,可以在整個枚舉過程中鎖定集合:

  1. QueuemyCollection=newQueue();  
  2. lock(myCollection.SyncRoot){  
  3. foreach(ObjectiteminmyCollection){  
  4. //Insertyourcodehere.  
  5. }  

以上介紹C# lock this問題

【編輯推薦】

  1. 分析C#不安全代碼
  2. 淺析C#調(diào)用ImageAnimator
  3. C#連接Access、SQL Server數(shù)據(jù)庫
  4. 淺談C#固定的和活動的變量
  5. 介紹C#中的值類型
責(zé)任編輯:佚名 來源: 博客園
相關(guān)推薦

2021-06-11 00:09:20

C#爬蟲版本

2009-08-10 13:49:50

C# txt文件

2009-08-11 10:42:14

C#算法

2009-08-26 15:16:29

C# lock關(guān)鍵字

2009-08-13 13:04:29

C# lock關(guān)鍵字

2009-08-13 17:25:18

C# Convert類

2009-08-07 14:47:23

C#路徑問題

2011-04-25 14:42:10

C#lock

2009-08-26 18:13:55

C#多線程lock

2009-08-11 09:40:22

張老師的生日問題C#算法

2012-02-02 14:34:37

C# Socket

2024-09-17 17:50:28

線程線程安全代碼

2009-09-15 17:46:08

C#綁定句柄無效

2009-08-28 10:14:45

C#內(nèi)存泄露

2009-08-06 16:01:30

C#接口成員

2009-09-03 14:38:28

C#日期格式化C#日期格式

2025-02-10 10:52:34

WinForm窗口閃爍C#

2009-09-02 14:30:35

C#換行符號

2009-08-05 08:42:41

C#中用Oracle執(zhí)DataSet

2011-04-25 15:15:00

C#
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號