鎖定與併發

2021-09-05 20:00:57 字數 1627 閱讀 3851

在多執行緒程式中,我們經常需要對要訪問的資源進行加鎖。加鎖的目的是為了同步對資源的訪問,但是,加鎖不可避免的會降低應用的併發量。那麼如何在需要加鎖的時候,盡可能地提高併發量了?下面是我的一些經驗,僅供參考。

1.首先,我們要控制好鎖的粒度。

鎖的粒度越大,能支援的併發就越小。

我們只需要將真正需要同步的**塊lock住,而不需要同步的**塊不要放在lock塊中。

當然,鎖的粒度也不是越小越好,粒度太細的鎖會導致程式設計很繁瑣,而且需要足夠的細心和全面考慮方可保證鎖不會出現問題。

在這點上,有乙個特別需要注意的是 -- 事件。事件最好不要在lock塊中觸發,因為你無法確定元件應用者的事件處理函式會執行多久。除非,你對一切了然於胸。

lock

(this

.locker)

2.杜絕死鎖的發生。當發生死鎖時,併發將降到最低。

3.區分讀寫。

我們經常使用lock關鍵字來鎖定資源,然而,lock沒有辦法區分讀寫。比如,如果當前同時有三個執行緒在訪問資源,且三個都是讀取資源,如果使用lock,那麼,在讀取資源上,它們也會被同步處理。幸運的是,.net為我們提供了讀寫鎖 -- readerwriterlock ,使用它,上面的例子便是三個執行緒可以同時讀取資源。

對於那種讀取多於修改的資源,區分讀寫可以極大地提公升併發量。

readerwriterlock的使用不如lock來得方便,為此,我封裝了smartrwlocker,它提供了和readerwriterlock一樣的功能,但是我們可以像使用lock一樣來使用它,如: 

using

(this

.smartrwlocker.lock(accessmode.read))

smartrwlocker的實現也相當簡單,如下所示:

//////

smartrwlocker 簡化了readerwriterlock的使用。

zhuweisky 2008.11.25

///public

class

smartrwlocker

}   

//////

accessmode 訪問鎖定資源的方式。

///public

enum

accessmode

public

class

lockingobject : idisposable

else

}#endregion

#region

idisposable 成員

public

void

dispose()

else

}#endregion}

2009.02.23 附加:

我們都知道,對於集合類,如lits<>,dictionary<,>等,

(1)如果其它執行緒在對其中的元素進行修改(如新增或刪除元素)時,正在對集合進行列舉的執行緒會丟擲異常。

(2)如果有乙個執行緒正在對集合進行修改,另外乙個執行緒呼叫contains/containskey,會丟擲異常嗎?答案是不會

鎖定與併發

在多執行緒程式中,我們經常需要對要訪問的資源進行加鎖。加鎖的目的是為了同步對資源的訪問,但是,加鎖不可避免的會降低應用的併發量。那麼如何在需要加鎖的時候,盡可能地提高併發量了?下面是我的一些經驗,僅供參考。1.首先,我們要控制好鎖的粒度。鎖的粒度越大,能支援的併發就越小。我們只需要將真正需要同步的 ...

悲觀鎖定與樂觀鎖定 第6章 鎖

expert oracle database architecture學習筆記 悲觀鎖定與樂觀鎖定 第6章.鎖 為了避免丟失更新,要使用某種鎖定策略,共有兩種鎖定策略 悲觀鎖定或樂觀鎖定。悲觀鎖定 pessimistic locking 使用者在螢幕上修改值之前,這個鎖定方法就要起作用。例如,使用者...

MYSQL排程與鎖定問題

4.5 排程與鎖定問題 前面各段主要將精力集中在使個別的查詢更快上。mysql還允許影響語句的排程特性,這樣會使來自幾個客戶機的查詢更好地協作,從而單個客戶機不會被鎖定太長的時間。更改排程特性還能保證特定的查詢處理得更快。我們先來看一下mysql的預設排程策略,然後 來看看為改變這個策略可使用什麼樣...