当需要线程安全收集(例如Set)时,如今的标准是什么。我应该自己同步它,还是有一个固有的线程安全集合?
当需要线程安全收集(例如Set)时,如今的标准是什么。我应该自己同步它,还是有一个固有的线程安全集合?
Answers:
.NET 4.0框架在System.Collections.Concurrent命名空间中引入了几个线程安全的集合:
ConcurrentBag <T>
表示线程安全的无序对象集合。ConcurrentDictionary <TKey,TValue>
表示可以由多个线程同时访问的键-值对的线程安全集合。ConcurrentQueue <T>
表示线程安全的先进先出(FIFO)集合。ConcurrentStack <T>
表示线程安全的后进先出(LIFO)集合。
.NET Framework中的其他集合默认情况下不是线程安全的,因此需要为每个操作锁定:
lock (mySet)
{
mySet.Add("Hello World");
}
在.net 4.0之前的版本中,.Net中的大多数集合都不是线程安全的。您必须自己做一些工作来处理同步:http : //msdn.microsoft.com/zh-cn/library/573ths2x.aspx
引用文章:
可以使用以下任何一种方法使Collections类成为线程安全的:
使用Synchronized方法创建一个线程安全的包装器,并通过该包装器专门访问该集合。
如果该类没有Synchronized方法,则从该类派生并使用SyncRoot属性实现Synchronized方法。
访问集合时,请在SyncRoot属性上使用锁定机制,例如C#中的lock语句(在Visual Basic中为SyncLock)。
Object thisLock = new Object();
......
lock (thisLock)
{
// Critical code section
}
在.net 4.0中,引入了System.Collections.Concurrent命名空间
除了System.Collections.Concurrent
.NET中非常有用的类外,一种也适用于.Net的标准技术(在大多数情况下是很少读取的情况下)(或者如果有频繁但非并发的写操作)也适用于.Net 。。
它具有一些在高并发程序中需要的属性:
限制:如果存在并发写入,则可能必须重试修改,因此并发写入越多,效率就越低。(这是工作中的乐观并发)
编辑斯科特·张伯伦(Scott Chamberlain)的评论提醒我,还有另一个限制:如果您的数据结构很大,并且修改频繁发生,那么就内存消耗和所涉及的复制的CPU成本而言,写所有写复制可能会被禁止。