阅读时是不是需要锁定非线程安全的集合?

Posted

技术标签:

【中文标题】阅读时是不是需要锁定非线程安全的集合?【英文标题】:Do I need to lock non-threadsafe collections when reading?阅读时是否需要锁定非线程安全的集合? 【发布时间】:2021-12-19 23:21:04 【问题描述】:

我有一个Hashset<string>,它可以被多个线程访问。每当我读或写这个时,我都会锁定它:

lock(lockObj)

   myCollection.Add(myString);

一般来说,阅读时我也必须这样做吗?这样做有什么好处吗?

【问题讨论】:

如果你这样做,在多线程环境中你永远不会遇到线程安全问题。还有其他选项完全取决于您的用例 您是否问在从多个线程同时读取Hashset<string> 时使用lock 是否有任何好处,并且没有线程可以改变Hashset<string>?如果是,并假设 Hashset<string> 不为空,您能否说明该集合是如何获得其值的? @TheodorZoulias 哈希集也在初始化和执行期间被写入(在读取它的同一时间段内),但每次写入时它都会被锁定。 【参考方案1】:

不,除了读取之外,还有写入时,您需要锁定它们。

只要不更改集合,就没有可能导致不一致的更改。

我经常进行非锁定多线程读取,即在包含应用程序在启动时加载且永不更改的元数据的集合上。

通常的问题是,为了提高性能(锁很昂贵),锁定是一种开销,只要在写入时没有发生读取(这些可能会不一致) - 根本不需要开销。

如果您必须写入,请使用 MultipleReaderSingleWriter 锁。这仅允许一次写入,但在没有写入发生时无限读取。以 RTFM 为例和方法详情。

【讨论】:

以上是关于阅读时是不是需要锁定非线程安全的集合?的主要内容,如果未能解决你的问题,请参考以下文章

在不锁定集合的情况下从通用集合中获取 Count 值是不是安全?

我们为什么在这里,特别是说ArrayList不是线程安全的?

线程安全集合

互斥锁

把非线程安全的集合转换为线程安全

初识多线程__下