久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C# Monitor:鎖定資源

 ontheroad96j47 2021-11-08

C#中,, 通過System.Threading.Monitor類可以實現(xiàn)多線程中對某些代碼塊的同步訪問,,以確保數(shù)據(jù)的安全性。

object obj=new object();

Monitor在鎖對象obj上會維持兩個線程隊列R和W以及一個引用T :

(1) T是對當(dāng)前獲得了obj鎖的線程的引用(設(shè)此線程為CurrThread); 

(2) R為就緒隊列,, 其上的線程已經(jīng)準(zhǔn)備好獲取obj鎖,。當(dāng)obj鎖被CurrThread釋放后(CurrThread可通過Monitor.Exit(obj)或 Monitor.Wait(obj)來釋放其所獲的obj鎖)這些線程就會去競爭obj鎖,獲得obj鎖的線程將被T引用; 線程調(diào)用Monitor.Enter(obj)或Monitor.TryEnter(obj)將會使該線程直接進(jìn)入R隊列,。

(3) W為等待隊列,,其上的線程是因為調(diào)用了Monitor.Wait(obj)而進(jìn)入W隊列的;W上的線程不會被OS直接調(diào)度執(zhí)行,,也就是說它們沒有準(zhǔn)備好獲取obj鎖,,就是說在等待隊列上的線程不能去獲得obj鎖當(dāng)前獲得obj鎖的線程CurrThread調(diào)用Monitor.Pulse(obj)或Monitor.PulseAll(obj)后會使W隊列中的第一個等待線程或所有等待線程被移至R隊列,,這時被移至R隊列的這些線程就有機(jī)會被OS直接調(diào)度執(zhí)行,,也就是有可以去競爭obj鎖。

lock 關(guān)鍵字

lock 關(guān)鍵字可以作為Monitor類的一個替代,。下面兩個代碼塊是等效的:

Monitor.Enter(this);//...Monitor.Exit(this);
lock (this){ //...}

在這里,,object 值與 lock 中的 object 值是一樣的。

簡而言之,,lock 的寫法是 Monitor 類的一種簡寫,。

【實例】將上一節(jié)《C# lock》實例中的 lock 關(guān)鍵字替換成 Monitor 類。

根據(jù)題目要求,,代碼如下,。

class Program{ public void PrintEven() { Monitor.Enter(this); try { for(int i = 0; i <= 10; i = i + 2) { Console.WriteLine(Thread.CurrentThread.Name + "--" + i); } } finally { Monitor.Exit(this); } } public void PrintOdd() { Monitor.Enter(this); try { for(int i = 1; i <= 10; i = i + 2) { Console.WriteLine(Thread.CurrentThread.Name + "--" + i); } } finally { Monitor.Exit(this); } } static void Main(string[] args) { Program program = new Program(); ThreadStart ts1 = new ThreadStart(program.PrintOdd); Thread t1 = new Thread(ts1); t1.Name = "打印奇數(shù)的線程"; t1.Start(); ThreadStart ts2 = new ThreadStart(program.PrintEven); Thread t2 = new Thread(ts2); t2.Name = "打印偶數(shù)的線程"; t2.Start(); }}

運行該程序,效果如下圖所示,。

Monitor 類的TryEnter() 方法在嘗試獲取一個對象上的顯式鎖方面和 Enter() 方法類似,。然而,它不像Enter()方法那樣會阻塞執(zhí)行,。如果線程成功進(jìn)入關(guān)鍵區(qū)域那么TryEnter()方法會返回true.

Monitor 類的用法雖然比 lock 關(guān)鍵字復(fù)雜,,但其能添加等待獲得鎖定的超時值,這樣就不會無限期等待獲得對象鎖,。

使用 TryEnter() 方法可以給它傳送一個超時值,,決定等待獲得對象鎖的最長時間。

使用 TryEnter() 方法設(shè)置獲得對象鎖的時間的代碼如下,。

Monitor.TryEnter(object, 毫秒數(shù) );

該方法能在指定的毫秒數(shù)內(nèi)結(jié)束線程,,這樣能避免線程之間的死鎖現(xiàn)象。

此外,,還能使用 Monitor 類中的 Wait() 方法讓線程等待一定的時間,,使用 Pulse() 方法通知處于等待狀態(tài)的線程,。

 C#中Monitor和Lock簡介及區(qū)別

1.Monitor.Enter(object)方法是獲取鎖,Monitor.Exit(object)方法是釋放鎖,,這就是Monitor最常用的兩個方法,,當(dāng)然在使用過程中為了避免獲取鎖之后因為異常,致鎖無法釋放,,所以需要在try{} catch(){}之后的finally{}結(jié)構(gòu)體中釋放鎖(Monitor.Exit()),。

  2.Monitor的常用屬性和方法:

    Enter(Object) 在指定對象上獲取排他鎖。

    Exit(Object) 釋放指定對象上的排他鎖,。

    IsEntered 確定當(dāng)前線程是否保留指定對象鎖,。

    Pulse 通知等待隊列中的線程鎖定對象狀態(tài)的更改。

    PulseAll 通知所有的等待線程對象狀態(tài)的更改,。

    TryEnter(Object) 試圖獲取指定對象的排他鎖,。

    TryEnter(Object, Boolean) 嘗試獲取指定對象上的排他鎖,并自動設(shè)置一個值,,指示是否得到了該鎖,。

    Wait(Object) 釋放對象上的鎖并阻止當(dāng)前線程,直到它重新獲取該鎖,。

                                       Lock關(guān)鍵字

  1.Lock關(guān)鍵字實際上是一個語法糖,,它將Monitor對象進(jìn)行封裝,給object加上一個互斥鎖,,A進(jìn)程進(jìn)入此代碼段時,,會給object對象加上互斥鎖,此時其他B進(jìn)程進(jìn)入此代碼段時檢查object對象是否有鎖,?如果有鎖則繼續(xù)等待A進(jìn)程運行完該代碼段并且解鎖object對象之后,B進(jìn)程才能夠獲取object對象為其加上鎖,,訪問代碼段,。

  2.Lock關(guān)鍵字封裝的Monitor對象結(jié)構(gòu)如下:

try { Monitor.Enter(obj); dosomething(); } catch(Exception ex) { } finally { Monitor.Exit(obj); }

 3.鎖定的對象應(yīng)該聲明為private static object obj = new object();盡量別用公共變量和字符串、this,、值類型,。

Monitor和Lock的區(qū)別

  1.Lock是Monitor的語法糖。

  2.Lock只能針對引用類型加鎖,。

  3.Monitor能夠?qū)χ殿愋瓦M(jìn)行加鎖,,實質(zhì)上是Monitor.Enter(object)時對值類型裝箱。

  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() { //做具體的事情 } }

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多