简体   繁体   English

这个非锁定的 TryGetValue() 字典访问线程安全吗?

[英]Is this non-locked TryGetValue() dictionary access thread-safe?

private object lockObj = new object();

private Dictionary<int, string> dict = new Dictionary<int, string>();

public string GetOrAddFromDict(int key)
{
    string value;

    // non-locked access:
    if (dict.TryGetValue(key, out value))
        return value;

    lock (this.lockObj)
    {
        if (dict.TryGetValue(key, out value))
            return value;

        string newValue = "value of " + key; // place long operation here
        dict.Add(key, newValue);

        return newValue;
    }
}

Question a: Is it thread-safe?问题a:它是线程安全的吗? If yes, why?如果是,为什么?

Question b: How is this double-TryGetValue() pattern called?问题 b:这个 double-TryGetValue() 模式是如何调用的?

a) This is not thread-safe, as the underlying Dictionary itself is not thread safe. a) 这不是线程安全的,因为底层Dictionary本身不是线程安全的。 If another thread is calling Add at the same time, undefined behavior can occur.如果另一个线程同时调用 Add,可能会发生未定义的行为。

b) This is effectively an attempt at double-checked locking . b) 这实际上是对双重检查锁定的尝试。

I would recommend using the ConcurrentDictionary class instead, as it's designed for this scenario.我建议改用ConcurrentDictionary class,因为它是为这种情况设计的。 Another option would be to use a ReaderWriterLockSlim (or ReaderWriterLock ), if you're not targetting .NET 4.0.如果您的目标不是 .NET 4.0,另一种选择是使用ReaderWriterLockSlim (或ReaderWriterLock )。

Question a: Is it thread-safe?问题a:它是线程安全的吗? If yes, why?如果是,为什么?

Not only is it not thread safe;它不仅不是线程安全的; it will also throw with NullReferenceException if accessed while another thread is reorganizing the hash buckets.如果在另一个线程正在重组 hash 存储桶时访问它,它也会抛出 NullReferenceException。 The lock statement is wicked fast, don't avoid it. lock 语句是邪恶的快,不要避免它。

Question b: How is this double-TryGetValue() pattern called?问题 b:这个 double-TryGetValue() 模式是如何调用的?

It's called a 'bug' by most people;)大多数人将其称为“错误”;)

Sadly, no.可悲的是没有。

I carry around a custom HashMap that has this property.我随身携带具有此属性的定制 HashMap。

The defect is in the rehash() function.缺陷在 rehash() function 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM