如果有一个可能会看到非常高并发只读访问的.NET集合(字典),是否仍需要保护它,这意味着我应该使用线程安全版本的集合或使用同步机制,还是线程安全只在存在并发读写活动的情况下才是一个话题?
如果有一个可能会看到非常高并发只读访问的.NET集合(字典),是否仍需要保护它,这意味着我应该使用线程安全版本的集合或使用同步机制,还是线程安全只在存在并发读写活动的情况下才是一个话题?
只有在读写操作并发发生时,对于集合的访问才需要同步。
如果您的集合在程序开始时只构建一次,然后仅用于读取其元素或遍历其内容,那么在读取操作周围添加任何额外的同步都是不必要的。
.NET框架提供了一个Immutable Collections包,以确保此执行流程。您可以预先构建不可变集合,之后您的代码就无法意外地修改它。
使用 ConcurrentDictionary
,它是一个线程安全的键/值对集合,允许多个线程同时访问。您可以在 ConcurrentDictionary 中阅读相关内容。
ConcurrentDictionary<TKey, TValue>
实现了 IReadOnlyCollection<T>
和 IReadOnlyDictionary<TKey, TValue>
接口,从 .NET Framework 4.6 开始;在之前的版本中,ConcurrentDictionary 类没有实现这些接口。
该类的所有操作都是原子性的并且是线程安全的,唯一的例外是接受委托的方法,即 AddOrUpdate 和 GetOrAdd。
对于字典的修改和写入操作,ConcurrentDictionary<TKey, TValue>
使用细粒度锁定来确保线程安全。
字典上的读取操作以无锁方式执行。
然而,为了避免在锁下执行未知代码所可能引发的问题,这些方法的委托者会在锁外部被调用。因此,由这些委托者执行的代码不受操作的原子性约束。
var coll = new[] { new Random() }; ... coll[0].Next()
。Random.Next()
不是线程安全的。 - xanatos