1. 程式人生 > >C# 中的線程安全集合類

C# 中的線程安全集合類

microsoft AI title .com interface arraylist block 分享 call

C# 的集合類型中, 都有Synchronized靜態方法, 和SyncRoot實例方法


對於ArrayList以及Hashtable 集合類來講,當需要做到線程安全的時候,最好利用其自帶的屬性SyncRoot 來做到,盡管也可以使用其Synchronized()方法來實現,但是使用屬性會更好。

線程安全集合:
BlockingCollection:
一個線程安全集合類,可為任何類型的集合提供線程安全

何時使用線程安全集合
該文章解釋了.net framework4新引入的五個專門支持多線程添加和刪除操作而設計的集合類型。不同於以前版本的中集合類型中的SyncRoot屬性 以及 Synchronized()方法,這些新類型使用了高效的鎖定和免鎖定同步機制

ConcurrentQueue(T)
ConcurrentStack(T)
ConcurrentDictionary(TKey, TValue)
ConcurrentBag(T)
BlockingCollection(T)

IProducerConsumerCollection<T>
定義了操作線程安全集合的方法,以供產品/使用者使用

示例請看:
IProducerConsumerCollection<T> Interface

官方示例給的是基於堆棧的線程安全實現,他繼承自該接口。然後加鎖lock來實現線程安全,該接口有四個方法:

技術分享圖片
[__DynamicallyInvokable]
public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection, IEnumerable
{
// Methods
[__DynamicallyInvokable]
void CopyTo(T[] array, int index);
[__DynamicallyInvokable]
T[] ToArray();
[__DynamicallyInvokable]
bool TryAdd(T item);
[__DynamicallyInvokable]
bool TryTake(out T item);
}除了CopyTo 之外的方法, 其余的都是該接口自己,基於堆棧的線程安全實現也就是加鎖, 那為什麽不調用堆棧數據結構中的SyncRoot 屬性和Synchronized()方法來加鎖實現同步?
技術分享圖片

參照:
C# Synchronized 和 SyncRoot 實現線程同步的源碼分析及泛型集合的線程安全訪問
SyncRoot 屬性

如果調用得是集合類的SyncRoot屬性的話,其鎖是對象級別的,而static 則是類型級別的。具體的回頭再研究下。

BlockingCollection類型這個集合類還是挺有意思的,他實現了IProducerConsumerCollection<T>的所有方法,可以實現任何自定義類型的線程安全。尤其是他的計時阻塞操作,具體代碼示例請看:
如何:在 BlockingCollection 中逐個添加和取出項
BlockingCollection 概述

C# 中的線程安全集合類