c# - TryGetValue 线程本身是否安全

标签 c# dictionary thread-safety trygetvalue

所以,我有一个 Dictionary<KType,VType> Foo

在一个线程中我有:

void Thread1() {
  ...
  if (!Foo.TryGetValue(key, out v)) {
    Foo.Add(new VType());
  }
  ...
}

唯一一次Foo曾被另一个线程访问过 TryGetValue .

那么,我需要锁多少钱?我可以做类似的事情吗:

void Thread1() {
  ...
  if (!Foo.TryGetValue(key, out v)) {
    lock (syncobj) {
      Foo.Add(new VType());
    }
  }
  ...
}
void Thread2() {
  ...
  lock (syncobj) {
    Foo.TryGetValue(key, out v))
  }
  ...
}

线程 1 占程序计算的 90%,TryGetValue被调用多次。因此,我希望不必每次都调用 lock。

最佳答案

如果任何有可能在另一个线程上同时发生更新TryGetValue,则每次都必须锁定执行。

TryGetValue 自身 是线程安全的,因为调用 TryGetValue 的多个线程不会相互干扰。但是,如果任何线程调用 Add,而其他线程正在对字典做 任何 其他事情,则存在损坏的可能性。

也就是说,锁可能并不可怕。你说 TryGetValue 被称为“多次”,但你没有说多久。更重要的是,您没有说明发生冲突的频率。在现代硬件上,一个无竞争的锁会花费大约 50 纳秒,所以这不是一个巨大的开销。您可能会尝试锁定以查看其性能。您也可以考虑 ReaderWriterLockSlim .

了解 ConcurrentDictionary 不是无锁数据结构很重要,尽管读取操作是以无锁方式完成的。它可能在您的情况下表现更好(可能会),但这不是给定的。

关于c# - TryGetValue 线程本身是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16929231/

相关文章:

C# 如何使用 USB 集线器和使用的 Controller 检查 USB 端口?

c# - C#中的集群服务共享资源

class - Excel VBA : Extract custom class from dictionary

ios - 修复小型基元的竞争条件有多重要?

java - 关于servlet的线程安全

c++ - 对内存中同一地址的写入之间可能存在数据竞争

c# - 带有 Directx 11 的 WPF

c# - 如何首先通过代码要求多对多关系

python - 排序嵌套的python字典

dictionary - 如何在不知道键的情况下从 F# Map 获取第一个键值对?