.NET中的线程安全集合
现在什么时候需要一个线程安全的收集标准(例如设置)。 我是否自己同步,还是有一个固有的线程安全集合?
.NET 4.0 Framework在System.Collections.Concurrent命名空间中引入了几个线程安全的集合:
ConcurrentBag <T>
表示一个线程安全的,无序的对象集合。ConcurrentDictionary <TKey,TValue>
表示可以由多个线程同时访问的键值对的线程安全集合。ConcurrentQueue <T>
表示线程安全的先入先出(FIFO)集合。ConcurrentStack <T>
代表线程安全的后进先出(LIFO)集合。
.NET Framework中的其他集合默认情况下不是线程安全的,需要为每个操作locking:
lock (mySet) { mySet.Add("Hello World"); }
.net 4.0中的大多数集合都不是线程安全的。 你将不得不自己做一些工作来处理同步: http : //msdn.microsoft.com/en-us/library/573ths2x.aspx
从文章引用:
集合类可以使用以下任何方法进行线程安全:
使用Synchronized方法创build一个线程安全的包装器,并通过该包装器专门访问该集合。
如果类没有Synchronized方法,则从该类派生并使用SyncRoot属性实现Synchronized方法。
访问集合时,请使用locking机制,例如C#中的locking语句(Visual Basic中的SyncLock),SyncRoot属性中的locking语句。
同步根属性
locking声明
Object thisLock = new Object(); ...... lock (thisLock) { // Critical code section }
在.net 4.0中引入了System.Collections.Concurrent命名空间
阻止收集
并发袋
并发队列
并行字典
Ordable分区器
分区
分区器T
.NET 4在System.Collections.Concurrent下提供了一组线程安全的集合
除了System.Collections.Concurrent
非常有用的类之外,在大多数读取很less更改的情况下(或者,如果存在频繁但非并发的写入)也可以应用于.Net的一种标准技术称为写入时复制 。
它具有一些高度并发程序中所需的特性:
- 集合对象实例本身是不可变的(即线程安全,可以安全枚举而不locking)
- 修改可以花费尽可能多的时间,读取的性能和并发性不受影响
- 可以一般地实现将任何不是线程安全的数据结构变成一个
限制:如果有并发写入,可能需要重新进行修改,所以并发写入越多,效率越低。 (这是乐观的并发工作)
编辑 Scott Chamberlain的评论提醒我还有另一个限制:如果你的数据结构很庞大,而且经常发生修改,那么在内存消耗和涉及拷贝的CPU成本方面,一次写入复制可能是禁止的。