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

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

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

简单聊聊C#中lock关键字

發(fā)布時(shí)間:2023/12/4 C# 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单聊聊C#中lock关键字 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為了避免多個(gè)線(xiàn)程同時(shí)操作同一資源,引起數(shù)據(jù)錯(cuò)誤,通常我們會(huì)將這個(gè)資源加上鎖,這樣在同一時(shí)間只能有一個(gè)線(xiàn)程操作資源。在C#中我們使用lock關(guān)鍵字來(lái)鎖定資源,那lock關(guān)鍵字是如何實(shí)現(xiàn)鎖定的呢?

我們先看一段代碼,非常簡(jiǎn)單的單例,相信你閉著眼睛也能寫(xiě)出來(lái)。代碼如下:

上面的代碼我就懶得解釋了。我們重點(diǎn)關(guān)注lock(locker)這行,就是這行限制了多個(gè)線(xiàn)程對(duì)大括號(hào)內(nèi)代碼的同時(shí)訪(fǎng)問(wèn)。下面我們就來(lái)講一個(gè)原理。不過(guò)講原理之前,還得和大家確認(rèn)一個(gè)知識(shí)點(diǎn),其實(shí)lock只是語(yǔ)法糖,其實(shí)現(xiàn)其實(shí)是Monitor類(lèi),所以上面的代碼和下面的代碼是相等。代碼如下:

沒(méi)有異議的話(huà),我們接著講。我們還是看lock(locker)這一行,簡(jiǎn)單地想一想,lock關(guān)鍵字把locker對(duì)象鎖住了,別的線(xiàn)程就進(jìn)不來(lái)了,那它是怎么鎖的呢?是在對(duì)象上打了什么標(biāo)記嗎?是把線(xiàn)程ID打到標(biāo)記嗎?我們先看一下堆中l(wèi)ocker的對(duì)象結(jié)構(gòu)。如下圖:

對(duì)象在堆中除了數(shù)據(jù)區(qū)以外,還有兩片區(qū)域:MethodTableRef、SyncBlockValue。其中MethodTableRef是指向MethodTable中這個(gè)類(lèi)型(Type)定義,簡(jiǎn)單說(shuō)就是這個(gè)對(duì)象是什么class定義的,這個(gè)不是我們今天討論的重點(diǎn),就過(guò)了。

我們重點(diǎn)看一下SyncBlockValue,這個(gè)值為DWORD類(lèi)型,占用4個(gè)字節(jié),也就是32位。這個(gè)值主要用來(lái)表示對(duì)象的不同功能,具體什么功能,要看這個(gè)32位如何賦值。一般將32位分為兩段,前6位用以表示不同的功能,后26位用以表示對(duì)象的hash值、或者是SyncBlock的索引值。如下圖:

回到lock(locker)這個(gè)主題上。其實(shí)你也應(yīng)該猜到,如果想實(shí)現(xiàn)lock(locker),只要在locker的前六位功能位上設(shè)置一個(gè)標(biāo)識(shí)位,標(biāo)識(shí)這個(gè)對(duì)象已經(jīng)被鎖住就行。但具體被哪個(gè)線(xiàn)程鎖住要記在哪邊呢?這時(shí)就要用到后面26位了。這時(shí)后26位會(huì)指向g_pSyncTable的某一項(xiàng)。g_pSyncTable是CLR維護(hù)的一個(gè)包SyncBlock項(xiàng)的全局?jǐn)?shù)組。這時(shí)的結(jié)構(gòu)如下圖:

我們結(jié)合上圖再來(lái)回顧一下整個(gè)流程:比如有兩個(gè)線(xiàn)程:線(xiàn)程A、線(xiàn)程B。線(xiàn)程A執(zhí)行到lock(locker)這一行時(shí),會(huì)先檢查locker的6個(gè)功能位中有沒(méi)有沒(méi)鎖住標(biāo)識(shí)位(假如第五位表示鎖),如果沒(méi)有鎖,則將第五位標(biāo)為1(不一定是1,這里只是舉例),然后到g_pSyncTable數(shù)組中申請(qǐng)一個(gè)SyncBlock,將當(dāng)前線(xiàn)程ID等信息記錄在里面,然后將這個(gè)SyncBlock的地址賦予locker對(duì)象的后26位值,這樣資源就被線(xiàn)程A鎖住了。這時(shí)線(xiàn)程B也執(zhí)行到lock(locker)這一行,它檢查前第五位,發(fā)現(xiàn)被鎖住了,就會(huì)到SyncBlock檢查鎖住的線(xiàn)程ID是否和自己一致,不一致的話(huà),它就會(huì)一直等待,直到線(xiàn)程A釋放鎖。

以上只是粗略地講述一下鎖的底層原理,可能有很多描述不準(zhǔn)確的地方,比如哪個(gè)功能位表示鎖,其實(shí)我也不太清楚,但大概原理應(yīng)該沒(méi)錯(cuò)。

最后留個(gè)問(wèn)題:如果鎖住的對(duì)象同時(shí)又想獲取HashCode,該如何存儲(chǔ)并得到呢?

總結(jié)

以上是生活随笔為你收集整理的简单聊聊C#中lock关键字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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