鎖:C#中Monitor和Lock以及區(qū)別
1.Monitor.Enter(object)方法是獲取鎖,Monitor.Exit(object)方法是釋放鎖,這就是Monitor最常用的兩個(gè)方法,當(dāng)然在使用過(guò)程中為了避免獲取鎖之后因?yàn)楫惓#骆i無(wú)法釋放,所以需要在try{} catch(){}之后的finally{}結(jié)構(gòu)體中釋放鎖(Monitor.Exit())。
2.Monitor的常用屬性和方法:
Enter(Object) 在指定對(duì)象上獲取排他鎖。
Exit(Object) 釋放指定對(duì)象上的排他鎖。
IsEntered 確定當(dāng)前線(xiàn)程是否保留指定對(duì)象鎖。
Pulse 通知等待隊(duì)列中的線(xiàn)程鎖定對(duì)象狀態(tài)的更改。
PulseAll 通知所有的等待線(xiàn)程對(duì)象狀態(tài)的更改。
TryEnter(Object) 試圖獲取指定對(duì)象的排他鎖。
TryEnter(Object, Boolean) 嘗試獲取指定對(duì)象上的排他鎖,并自動(dòng)設(shè)置一個(gè)值,指示是否得到了該鎖。
Wait(Object) 釋放對(duì)象上的鎖并阻止當(dāng)前線(xiàn)程,直到它重新獲取該鎖。
Lock關(guān)鍵字
1.Lock關(guān)鍵字實(shí)際上是一個(gè)語(yǔ)法糖,它將Monitor對(duì)象進(jìn)行封裝,給object加上一個(gè)互斥鎖,A進(jìn)程進(jìn)入此代碼段時(shí),會(huì)給object對(duì)象加上互斥鎖,此時(shí)其他B進(jìn)程進(jìn)入此代碼段時(shí)檢查object對(duì)象是否有鎖?如果有鎖則繼續(xù)等待A進(jìn)程運(yùn)行完該代碼段并且解鎖object對(duì)象之后,B進(jìn)程才能夠獲取object對(duì)象為其加上鎖,訪(fǎng)問(wèn)代碼段。
2.Lock關(guān)鍵字封裝的Monitor對(duì)象結(jié)構(gòu)如下:
try{Monitor.Enter(obj);dosomething();}catch(Exception ex){}finally{Monitor.Exit(obj);}
3.鎖定的對(duì)象應(yīng)該聲明為private static object obj = new object();盡量別用公共變量和字符串、this、值類(lèi)型。
Monitor和Lock的區(qū)別
1.Lock是Monitor的語(yǔ)法糖。
2.Lock只能針對(duì)引用類(lèi)型加鎖。
3.(使用?Monitor?鎖定對(duì)象(即引用類(lèi)型)而不是值類(lèi)型。)。
4.Monitor還有其他的一些功能。
class Program{private static object obj = new object();public void LockSomething(){lock (obj){dosomething();}}public void MonitorSomeThing(){try{Monitor.Enter(obj);dosomething();}catch(Exception ex){}finally{Monitor.Exit(obj);}}public void dosomething(){//做具體的事情}}
Monitor?類(lèi)通過(guò)向單個(gè)線(xiàn)程授予對(duì)象鎖來(lái)控制對(duì)對(duì)象的訪(fǎng)問(wèn)。對(duì)象鎖提供限制訪(fǎng)問(wèn)代碼塊(通常稱(chēng)為臨界區(qū))的能力。當(dāng)一個(gè)線(xiàn)程擁有對(duì)象的鎖時(shí),其他任何線(xiàn)程都不能獲取該鎖。還可以使用?Monitor?來(lái)確保不會(huì)允許其他任何線(xiàn)程訪(fǎng)問(wèn)正在由鎖的所有者執(zhí)行的應(yīng)用程序代碼節(jié),除非另一個(gè)線(xiàn)程正在使用其他的鎖定對(duì)象執(zhí)行該代碼。
Monitor?具有以下功能:
它根據(jù)需要與某個(gè)對(duì)象相關(guān)聯(lián)。
它是未綁定的,也就是說(shuō)可以直接從任何上下文調(diào)用它。
不能創(chuàng)建?Monitor?類(lèi)的實(shí)例。
將為每個(gè)同步對(duì)象來(lái)維護(hù)以下信息:
對(duì)當(dāng)前持有鎖的線(xiàn)程的引用。
對(duì)就緒隊(duì)列的引用,它包含準(zhǔn)備獲取鎖的線(xiàn)程。
對(duì)等待隊(duì)列的引用,它包含正在等待鎖定對(duì)象狀態(tài)變化通知的線(xiàn)程。
下表描述了訪(fǎng)問(wèn)同步對(duì)象的線(xiàn)程可以采取的操作:
操作 | 說(shuō)明 |
|---|---|
Enter,?TryEnter | 獲取對(duì)象鎖。此操作同樣會(huì)標(biāo)記臨界區(qū)的開(kāi)頭。其他任何線(xiàn)程都不能進(jìn)入臨界區(qū),除非它使用其他鎖定對(duì)象執(zhí)行臨界區(qū)中的指令。 |
Wait | 釋放對(duì)象上的鎖以便允許其他線(xiàn)程鎖定和訪(fǎng)問(wèn)該對(duì)象。在其他線(xiàn)程訪(fǎng)問(wèn)對(duì)象時(shí),調(diào)用線(xiàn)程將等待。脈沖信號(hào)用于通知等待線(xiàn)程有關(guān)對(duì)象狀態(tài)的更改。 |
Pulse?(信號(hào)),?PulseAll | 向一個(gè)或多個(gè)等待線(xiàn)程發(fā)送信號(hào)。該信號(hào)通知等待線(xiàn)程鎖定對(duì)象的狀態(tài)已更改,并且鎖的所有者準(zhǔn)備釋放該鎖。等待線(xiàn)程被放置在對(duì)象的就緒隊(duì)列中以便它可以最后接收對(duì)象鎖。一旦線(xiàn)程擁有了鎖,它就可以檢查對(duì)象的新?tīng)顟B(tài)以查看是否達(dá)到所需狀態(tài)。 |
Exit | 釋放對(duì)象上的鎖。此操作還標(biāo)記受鎖定對(duì)象保護(hù)的臨界區(qū)的結(jié)尾。 |
????使用?Enter?和?Exit?方法標(biāo)記臨界區(qū)的開(kāi)頭和結(jié)尾。如果臨界區(qū)是一個(gè)連續(xù)指令集,則由?Enter?方法獲取的鎖將保證只有一個(gè)線(xiàn)程可以使用鎖定對(duì)象執(zhí)行所包含的代碼。在這種情況下,建議您將這些指令放在?try?塊中,并將?Exit?指令放在?finally?塊中。此功能通常用于同步對(duì)類(lèi)的靜態(tài)或?qū)嵗椒ǖ脑L(fǎng)問(wèn)。如果實(shí)例方法需要同步線(xiàn)程訪(fǎng)問(wèn),則它將使用當(dāng)前實(shí)例作為要鎖定的對(duì)象調(diào)用?Enter?和對(duì)應(yīng)的?Exit?方法。由于只能有一個(gè)線(xiàn)程持有當(dāng)前實(shí)例上的鎖,因此該方法一次只能由一個(gè)線(xiàn)程來(lái)執(zhí)行。靜態(tài)方法是使用當(dāng)前實(shí)例的 Type 作為鎖定對(duì)象以類(lèi)似的方式來(lái)保護(hù)的。Enter?和?Exit?方法提供的功能與 C#?lock?語(yǔ)句(在 Visual Basic 中為?SyncLock)提供的功能相同,區(qū)別在于?lock?和?SyncLock?以?try…finally?塊(在 Visual Basic 中為?Try…Finally)來(lái)包裝?Exit?方法,以確保釋放監(jiān)視器。
????如果臨界區(qū)跨越整個(gè)方法,則可以通過(guò)將?System.Runtime.CompilerServices.MethodImplAttribute?放置在方法上并在?MethodImplAttribute?的構(gòu)造函數(shù)中指定 Synchronized 值來(lái)實(shí)現(xiàn)上述鎖定功能。使用該屬性后就不需要?Enter?和?Exit?語(yǔ)句了。請(qǐng)注意,該屬性將使當(dāng)前線(xiàn)程持有鎖,直到方法返回;如果可以更早釋放鎖,則使用?Monitor?類(lèi)或 C#lock?語(yǔ)句而不是該屬性。
盡管鎖定和釋放給定對(duì)象的?Enter?和?Exit?語(yǔ)句可以跨越成員或類(lèi)的邊界或同時(shí)跨越兩者的邊界,但并不推薦這樣做。
當(dāng)選擇要同步的對(duì)象時(shí),應(yīng)只鎖定私有或內(nèi)部對(duì)象。鎖定外部對(duì)象可能導(dǎo)致死鎖,這是因?yàn)椴幌嚓P(guān)的代碼可能會(huì)出于不同的目的而選擇鎖定相同的對(duì)象。
以上來(lái)自MSDN、@陳臥龍的博客
出處:https://www.cnblogs.com/chenwolong/p/7503977.html
版權(quán)申明:本文來(lái)源于網(wǎng)友收集或網(wǎng)友投稿,僅供學(xué)習(xí)交流之用,如果有侵權(quán),請(qǐng)轉(zhuǎn)告版主或者留言,本公眾號(hào)立即刪除。
支持小微:
騰訊云 新年活動(dòng)!玩服務(wù)器的可以搞搞,老客戶(hù)也可以參加!
輕量服務(wù)器??2核4G8M80G?222元/3年??
爆款1核2G云服務(wù)器首年38元??
鏈接:https://curl.qcloud.com/bR8ycXZa
右下角,您點(diǎn)一下在看圖片
小微工資漲1毛
商務(wù)合作QQ:185601686
