日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Lock VS Monitor

發(fā)布時(shí)間:2023/12/4 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Lock VS Monitor 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

介紹


對(duì)開(kāi)發(fā)人員來(lái)說(shuō),處理關(guān)鍵代碼部分的多線程應(yīng)用程序是非常重要的。

Monitor和lock是c#語(yǔ)言中多線程應(yīng)用程序中提供線程安全的方法(lock關(guān)鍵字的本質(zhì)就是對(duì)Monitor的封裝)。兩者都提供了一種機(jī)制來(lái)確保只有一個(gè)線程同時(shí)執(zhí)行代碼,以避免代碼功能被其他線程中斷

c#中 Lock關(guān)鍵字確保一個(gè)線程同時(shí)執(zhí)行一段代碼。lock關(guān)鍵字確保一個(gè)線程不進(jìn)入代碼的鎖定區(qū),而另一個(gè)線程在鎖定區(qū)內(nèi)。

Lock關(guān)鍵字是Monitor的“快捷方式”。

namespace Monitor_Lock { class Program { static readonly object _object = new object(); static void TestLock() { lock (_object) { Thread.Sleep(100); Console.WriteLine(Environment.TickCount); } } static void Main(string[] args) { for (int i = 0; i < 10; i++) { ThreadStart start = new ThreadStart(TestLock); new Thread(start).Start(); } Console.ReadLine(); } } }

輸出:

這里我們看到一個(gè)靜態(tài)方法“TestLock”,它在對(duì)象上使用lock語(yǔ)句。在新線程上多次調(diào)用TestLock方法時(shí),每次調(diào)用該方法都會(huì)訪問(wèn)該鎖的對(duì)象是否釋放。

Main方法創(chuàng)建十個(gè)新線程,然后在每個(gè)線程上開(kāi)始調(diào)用。方法TestLock被調(diào)用十次,但是Environment.TickCount計(jì)數(shù)器顯示受保護(hù)的方法區(qū)域是按順序執(zhí)行的,大約相隔100毫秒。

如果另一個(gè)線程試圖進(jìn)入一個(gè)鎖定的代碼,它將等待,阻塞,直到對(duì)象被釋放。


lock關(guān)鍵字通過(guò)獲取給定對(duì)象的互斥鎖,將語(yǔ)句塊標(biāo)記為一個(gè)臨界段,執(zhí)行語(yǔ)句,然后釋放鎖,


Monitor


Monitor提供了一種同步對(duì)象訪問(wèn)的機(jī)制。它可以通過(guò)獲取一個(gè)重要的鎖來(lái)實(shí)現(xiàn),這樣一次只有一個(gè)線程可以進(jìn)入給定的代碼段。Monitor與lock沒(méi)有什么不同,但是Monitor類(lèi)對(duì)試圖訪問(wèn)相同代碼鎖的各個(gè)線程的同步提供了更多的控制。


使用Monitor可以確保不允許任何其他線程訪問(wèn)鎖所有者正在執(zhí)行的應(yīng)用程序代碼段,除非其他線程使用不同的鎖定對(duì)象執(zhí)行代碼。


Monitor類(lèi)有以下方法通過(guò)獲取和釋放鎖來(lái)同步訪問(wèn)代碼的某個(gè)區(qū)域


Enter(Object)

在指定對(duì)象上獲取排他鎖。

Enter(Object, Boolean)

獲取指定對(duì)象上的排他鎖,并自動(dòng)設(shè)置一個(gè)值,指示是否獲取了該鎖。

Exit(Object)

釋放指定對(duì)象上的排他鎖。

IsEntered(Object)

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

Pulse(Object)

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

PulseAll(Object)

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

TryEnter(Object, TimeSpan, Boolean)

在指定的一段時(shí)間內(nèi)嘗試獲取指定對(duì)象上的排他鎖,并自動(dòng)設(shè)置一個(gè)值,指示是否獲得了該鎖。

TryEnter(Object, Int32, Boolean)

在指定的毫秒數(shù)內(nèi)嘗試獲取指定對(duì)象上的排他鎖,并自動(dòng)設(shè)置一個(gè)值,指示是否獲取了該鎖。

TryEnter(Object, TimeSpan)

在指定的時(shí)間內(nèi)嘗試獲取指定對(duì)象上的排他鎖。

TryEnter(Object, Boolean)

嘗試獲取指定對(duì)象上的排他鎖,并自動(dòng)設(shè)置一個(gè)值,指示是否獲取了該鎖。

TryEnter(Object)

嘗試獲取指定對(duì)象的排他鎖。

TryEnter(Object, Int32)

在指定的毫秒數(shù)內(nèi)嘗試獲取指定對(duì)象上的排他鎖。

Wait(Object, Int32, Boolean)

釋放對(duì)象上的鎖并阻止當(dāng)前線程,直到它重新獲取該鎖。?如果已用指定的超時(shí)時(shí)間間隔,則線程進(jìn)入就緒隊(duì)列。?此方法還指定是否在等待之前退出上下文的同步域(如果處于同步上下文中的話)然后重新獲取該同步域。

Wait(Object)

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

Wait(Object, Int32)

釋放對(duì)象上的鎖并阻止當(dāng)前線程,直到它重新獲取該鎖。?如果已用指定的超時(shí)時(shí)間間隔,則線程進(jìn)入就緒隊(duì)列。

Wait(Object, TimeSpan)

釋放對(duì)象上的鎖并阻止當(dāng)前線程,直到它重新獲取該鎖。?如果已用指定的超時(shí)時(shí)間間隔,則線程進(jìn)入就緒隊(duì)列。

Wait(Object, TimeSpan, Boolean)

釋放對(duì)象上的鎖并阻止當(dāng)前線程,直到它重新獲取該鎖。?如果已用指定的超時(shí)時(shí)間間隔,則線程進(jìn)入就緒隊(duì)列。?可以在等待之前退出同步上下文的同步域,隨后重新獲取該域。

Monitor鎖定對(duì)象(即引用類(lèi)型),而不是值類(lèi)型。雖然您可以傳遞一個(gè)值類(lèi)型來(lái)進(jìn)入和退出,但是對(duì)于每個(gè)調(diào)用,它都是單獨(dú)裝箱的。

Wait在鎖被持有并等待被通知時(shí)釋放鎖。當(dāng)Wait被通知時(shí),它返回并再次獲得鎖。Pulse和PulseAll都為等待隊(duì)列中的下一個(gè)線程的開(kāi)始發(fā)出信號(hào)。

下面是使用Monitor的語(yǔ)法。

try { int x = 1; Monitor.Enter(x); try { // Code that needs to be protected by the monitor. } finally { Monitor.Exit(x); } } catch (SynchronizationLockException SyncEx) { Console.WriteLine("A SynchronizationLockException occurred. Message:"); Console.WriteLine(SyncEx.Message); }

簡(jiǎn)單例子:

namespace Monitor_Lock { class Program { static readonly object _object = new object(); public static void PrintNumbers() { Monitor.Enter(_object); try { for (int i = 0; i < 5; i++) { Thread.Sleep(100); Console.Write(i + ","); } Console.WriteLine(); } finally { Monitor.Exit(_object); } } static void TestLock() { lock (_object) { Thread.Sleep(100); Console.WriteLine(Environment.TickCount); } } static void Main(string[] args) { Thread[] Threads = new Thread[3]; for (int i = 0; i < 3; i++) { Threads[i] = new Thread(new ThreadStart(PrintNumbers)); Threads[i].Name = "Child " + i; } foreach (Thread t in Threads) t.Start(); Console.ReadLine(); } } }

輸出:

在c# 4.0中,Monitor.Enter(_object,ref _lockTaken)重載函數(shù)獲取一個(gè)獨(dú)占鎖和指定的對(duì)象,并自動(dòng)設(shè)置一個(gè)值,該值指示鎖是否被獲取。


class Program { static readonly object _object = new object(); public static void PrintNumbers() { Boolean _lockTaken = false; Monitor.Enter(_object,ref _lockTaken); try { for (int i = 0; i < 5; i++) { Thread.Sleep(100); Console.Write(i + ","); } Console.WriteLine(); } finally { if (_lockTaken) { Monitor.Exit(_object); } } } }

與lock等價(jià)的Monitor實(shí)現(xiàn)

Monitor.Enter(object); try { // Your code here... } finally { Monitor.Exit(object); }


結(jié)論

Monitor類(lèi)是一個(gè)靜態(tài)類(lèi),不能創(chuàng)建它的實(shí)例。

Monitor類(lèi)對(duì)象使用 Monitor.TryEnter, and Monitor.Exit 方法。一旦鎖定了代碼區(qū)域,就可以使用 Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll 等方法。

Lock和monitor在多線程中基本上用于相同的目的,Monitor的不同之處在于,當(dāng)我們希望對(duì)運(yùn)行特定代碼段的多個(gè)線程的同步進(jìn)行更多控制時(shí)更有效

總結(jié)

以上是生活随笔為你收集整理的Lock VS Monitor的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。