ConcurrentDictionary构造函数线程安全吗?

Sha*_*123 1 c#

例如,如果我有以下代码:

if (dictionary == null) {
    dictionary = new ConcurrentDictionary();
}
Run Code Online (Sandbox Code Playgroud)

多个线程可以读取它是否为null并同时创建新的ConcurrentDictionaries?

我在谈论System.Collections.Concurrent提供的ConcurrentDictionary

https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx

M.k*_*ary 5

ConcurrentDictionary是线程安全的.但是你展示的代码与内部代码无关ConcurrentDictionary.一切都ConcurrentDictionary在你的责任范围内.所以你应该确保只进行一次初始化.

一种方法是使用Lazy(T).

Lazy<ConcurrentDictionary> _dictionary = new Lazy<ConcurrentDictionary>(() => new ConcurrentDictionary());
Run Code Online (Sandbox Code Playgroud)

只需调用Value即可获取字典实例.Lazy只会初始化一次字典,并且还会处理初始化部分的线程安全性.

var dic = _dictionary.Value; // extract instance.
Run Code Online (Sandbox Code Playgroud)


Jon*_*nna 5

大多数构造函数都是线程安全的,因为它们只发生在一个线程上。如果它们访问静态字段或调用非\xe2\x80\x93线程安全委托或其他东西,则存在例外,但它们很少见(通常是一个坏主意)。

\n\n

但这不是您问题的关键,因为在您的示例中,可能竞争的不是构造函数,而是作业。

\n\n

如果另一个线程可以访问dictionary,那么确实存在竞争,并且一个线程可以分配给dictionary另一个线程以被另一个线程覆盖(并且可能有一个时期,两个线程认为dictionary具有不同的值)。

\n\n

可能是个问题。它可能只是次优的(例如,并发字典被用作缓存,一些缓存的值丢失并且必须重新计算,但事情仍然有效)或者它可能是灾难性的。如果dictionary对多个线程可见,那么您应该锁定并重新测试,使用Interlocked.CompareExchangeLazy<ConcurrentDictionary>

\n