.NET集合的只读并发访问需要保护吗?

3

如果有一个可能会看到非常高并发只读访问的.NET集合(字典),是否仍需要保护它,这意味着我应该使用线程安全版本的集合或使用同步机制,还是线程安全只在存在并发读写活动的情况下才是一个话题?

2个回答

4

只有在读写操作并发发生时,对于集合的访问才需要同步。

如果您的集合在程序开始时只构建一次,然后仅用于读取其元素或遍历其内容,那么在读取操作周围添加任何额外的同步都是不必要的。

.NET框架提供了一个Immutable Collections包,以确保此执行流程。您可以预先构建不可变集合,之后您的代码就无法意外地修改它。


访问集合是安全的,但元素可能不安全使用。例如 var coll = new[] { new Random() }; ... coll[0].Next()Random.Next() 不是线程安全的。 - xanatos
你的意思是xanatos,同时对项目进行操作可能不是线程安全的吗? - whatever
如果项目本身是可变的,那么对于从集合中获取的单个项目的操作需要进行可变操作的同步。 - Sergey Kalinichenko

0

使用 ConcurrentDictionary,它是一个线程安全的键/值对集合,允许多个线程同时访问。您可以在 ConcurrentDictionary 中阅读相关内容。

ConcurrentDictionary<TKey, TValue> 实现了 IReadOnlyCollection<T>IReadOnlyDictionary<TKey, TValue> 接口,从 .NET Framework 4.6 开始;在之前的版本中,ConcurrentDictionary 类没有实现这些接口。

该类的所有操作都是原子性的并且是线程安全的,唯一的例外是接受委托的方法,即 AddOrUpdate 和 GetOrAdd。

对于字典的修改和写入操作,ConcurrentDictionary<TKey, TValue> 使用细粒度锁定来确保线程安全。

字典上的读取操作以无锁方式执行

然而,为了避免在锁下执行未知代码所可能引发的问题,这些方法的委托者会在锁外部被调用。因此,由这些委托者执行的代码不受操作的原子性约束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接