C#中實(shí)現(xiàn)線(xiàn)程同步lock關(guān)鍵字的用法詳解
1. lock關(guān)鍵字保證一個(gè)代碼塊在執(zhí)行的過(guò)程中不會(huì)受到其他線(xiàn)程的干擾,這是通過(guò)在該代碼塊的運(yùn)行過(guò)程中對(duì)特定的對(duì)象加互斥鎖來(lái)實(shí)現(xiàn)的。
2. lock關(guān)鍵字的參數(shù)必須是引用類(lèi)型的對(duì)象。lock對(duì)基本數(shù)據(jù)類(lèi)型如int,long等無(wú)效,因?yàn)樗饔玫念?lèi)型必須是對(duì)象。如果傳入long類(lèi)型數(shù)據(jù),勢(shì)必被轉(zhuǎn)換為Int64結(jié)構(gòu)類(lèi)型,則加鎖的是全新的對(duì)象引用。如果需要對(duì)它們進(jìn)行互斥訪(fǎng)問(wèn)限制,可以使用System.Threading.Interlocked類(lèi)提供的方法,這個(gè)類(lèi)是提供原子操作的。
3. lock(this)的使用要慎重。共有類(lèi)型中使用lock(this),如果新的對(duì)象被創(chuàng)建并加鎖,極易造成死鎖。
4. 鎖定ICollection類(lèi)型對(duì)象時(shí),應(yīng)lock其SyncRoot屬性。
SyncRoot屬性在接口ICollection中聲明,其實(shí)現(xiàn)方式各不相同。
例如在Collection(System.Collections.ObjectModel)中實(shí)現(xiàn)如下:
object ICollection.SyncRoot { get { if (this._syncRoot == null) { ICollection items = this.items as ICollection; if (items != null) { this._syncRoot = items.SyncRoot; } else { Interlocked.CompareExchange(ref this._syncRoot, new object(), null); } } return this._syncRoot; } }
而在List<T>,ArrayList等類(lèi)中實(shí)現(xiàn)如下:
object ICollection.SyncRoot { get { if (this._syncRoot == null) { Interlocked.CompareExchange(ref this._syncRoot, new object(), null); } return this._syncRoot; } }
在Array類(lèi)中則直接返回了this:
public object SyncRoot { get { return this; } }
5. lock關(guān)鍵字是用Monitor(管程)類(lèi)實(shí)現(xiàn)的
lock(x) { DoSomething(); }
System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); try { DoSomething(); } finally { System.Threading.Monitor.Exit(obj); }
以上兩段代碼是等效的。(MSDN)
使用lock關(guān)鍵字相對(duì)于Monitor類(lèi)在使用上更簡(jiǎn)單,也更加保險(xiǎn)。
- 使用Golang的singleflight防止緩存擊穿的方法
- 一篇文章帶你輕松了解C# Lock關(guān)鍵字
- C#筆試題之同線(xiàn)程Lock語(yǔ)句遞歸不會(huì)死鎖
- C#使用Interlocked實(shí)現(xiàn)線(xiàn)程同步
- C#中使用Interlocked進(jìn)行原子操作的技巧
- 如何使用C#讀寫(xiě)鎖ReaderWriterLockSlim
- C#中的lock、Monitor、Mutex學(xué)習(xí)筆記
- C#中l(wèi)ock用法詳解
- C#中l(wèi)ock死鎖實(shí)例教程
- c#多線(xiàn)程中Lock()關(guān)鍵字的用法小結(jié)
- c# 如何用lock解決緩存擊穿
相關(guān)文章
Unity?使用tiledmap解析地圖的詳細(xì)過(guò)程
這篇文章主要介紹了Unity?使用tiledmap解析地圖,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04WPF自定義MenuItem樣式的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于WPF自定義MenuItem樣式的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用WPF具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06C#實(shí)現(xiàn)的sqlserver操作類(lèi)實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)的sqlserver操作類(lèi),結(jié)合具體實(shí)例形式分析了C#針對(duì)sqlserver數(shù)據(jù)庫(kù)進(jìn)行連接、查詢(xún)、更新、關(guān)閉等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06