C# ConcurrentDictionary构造函数是线程安全的吗?
例如,如果我有如下代码:C# ConcurrentDictionary构造函数是线程安全的吗?,c#,C#,例如,如果我有如下代码: if (dictionary == null) { dictionary = new ConcurrentDictionary(); } 多个线程是否可以读取它的null值并同时创建新的ConcurrentDictionary 我说的是System.Collections.Concurrent提供的ConcurrentDictionary 实例化后,它是线程安全的(即多个线程可以添加/访问/从中访问而不会出现问题)。在您的情况下,您需要使语句实例化为线程安全的
if (dictionary == null) {
dictionary = new ConcurrentDictionary();
}
多个线程是否可以读取它的null值并同时创建新的ConcurrentDictionary
我说的是System.Collections.Concurrent提供的ConcurrentDictionary
实例化后,它是线程安全的(即多个线程可以添加/访问/从中访问而不会出现问题)。在您的情况下,您需要使语句实例化为线程安全的,您可以使用关键字:
实例化后,它是线程安全的(即多个线程可以添加/访问/从中访问而不会出现问题)。在您的情况下,您需要使语句实例化为线程安全的,您可以使用关键字:
ConcurrentDictionary
是线程安全的。但您显示的代码与ConcurrentDictionary
的内部结构无关。一切外部的ConcurrentDictionary
都由您负责。因此,您应该确保只进行一次初始化
一种方法是使用
ConcurrentDictionary
是线程安全的。但您显示的代码与ConcurrentDictionary
的内部结构无关。一切外部的ConcurrentDictionary
都由您负责。因此,您应该确保只进行一次初始化
一种方法是使用
大多数构造函数都是线程安全的,因为它们只发生在一个线程上。如果它们访问静态字段或调用非线程安全的委托或其他东西,则会出现异常,但这种情况很少见(通常是个坏主意) 这不是你问题的关键,因为在你的例子中,不是构造器,而是赋值 如果另一个线程可以访问
字典
,那么确实存在竞争,一个线程可以分配给字典
,只是被另一个线程覆盖(并且可能有一段时间,两个线程将字典
视为具有不同的值)
这可能是个问题。它可能仅仅是次优的(例如,并发字典被用作缓存,一些缓存值丢失,必须重新计算,但仍能正常工作),或者可能是灾难性的。如果多个线程可以看到
字典
,则应锁定并重新测试,使用联锁。CompareExchange
或惰性
大多数构造函数都是线程安全的,因为它们只发生在一个线程上。如果它们访问静态字段或调用非线程安全的委托或其他东西,则会出现异常,但这种情况很少见(通常是个坏主意)
这不是你问题的关键,因为在你的例子中,不是构造器,而是赋值
如果另一个线程可以访问字典
,那么确实存在竞争,一个线程可以分配给字典
,只是被另一个线程覆盖(并且可能有一段时间,两个线程将字典
视为具有不同的值)
这可能是个问题。它可能仅仅是次优的(例如,并发字典被用作缓存,一些缓存值丢失,必须重新计算,但仍能正常工作),或者可能是灾难性的。如果多个线程可以看到
字典
,则应锁定并重新测试,使用联锁。CompareExchange
或Lazy
该代码示例不是线程安全的,因为它允许多个线程查看“字典”在新运算符更改以分配新实例之前,变量为null
使用lock对象和lock语句是有效的,但是每次使用字典时都会添加一个lock变量并导致锁惩罚
以下版本不需要锁变量,并且不会在每次使用dictionary字段时产生锁惩罚
if( dictionary == null )
Interlocked.CompareExchange( ref dictionary, new ConcurrentDictionary(), null );
dictionary.xxx()
- 请记住,ConcurrentDictionary是一个泛型类型,因此上面的新运算符需要包含类型参数
if( dictionary == null )
Interlocked.CompareExchange( ref dictionary, new ConcurrentDictionary(), null );
dictionary.xxx()
- 请记住,ConcurrentDictionary是一个泛型类型,因此上面的新运算符需要包含类型参数
var dic = _dictionary.Value; // extract instance.
if( dictionary == null )
Interlocked.CompareExchange( ref dictionary, new ConcurrentDictionary(), null );
dictionary.xxx()