C#中實(shí)現(xiàn)線程同步lock關(guān)鍵字的用法詳解
1. lock關(guān)鍵字保證一個(gè)代碼塊在執(zhí)行的過程中不會(huì)受到其他線程的干擾,這是通過在該代碼塊的運(yùn)行過程中對特定的對象加互斥鎖來實(shí)現(xiàn)的。
2. lock關(guān)鍵字的參數(shù)必須是引用類型的對象。lock對基本數(shù)據(jù)類型如int,long等無效,因?yàn)樗饔玫念愋捅仨毷菍ο?。如果傳入long類型數(shù)據(jù),勢必被轉(zhuǎn)換為Int64結(jié)構(gòu)類型,則加鎖的是全新的對象引用。如果需要對它們進(jìn)行互斥訪問限制,可以使用System.Threading.Interlocked類提供的方法,這個(gè)類是提供原子操作的。
3. lock(this)的使用要慎重。共有類型中使用lock(this),如果新的對象被創(chuàng)建并加鎖,極易造成死鎖。
4. 鎖定ICollection類型對象時(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等類中實(shí)現(xiàn)如下:
object ICollection.SyncRoot { get { if (this._syncRoot == null) { Interlocked.CompareExchange(ref this._syncRoot, new object(), null); } return this._syncRoot; } }
在Array類中則直接返回了this:
public object SyncRoot { get { return this; } }
5. lock關(guān)鍵字是用Monitor(管程)類實(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)鍵字相對于Monitor類在使用上更簡單,也更加保險(xiǎn)。
相關(guān)文章
WPF自定義MenuItem樣式的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于WPF自定義MenuItem樣式的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用WPF具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06C#實(shí)現(xiàn)的sqlserver操作類實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)的sqlserver操作類,結(jié)合具體實(shí)例形式分析了C#針對sqlserver數(shù)據(jù)庫進(jìn)行連接、查詢、更新、關(guān)閉等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06