TryGetValue线程本身是否安全

时间:2013-06-04 23:41:09

标签: 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))
  }
  ...
}

Thread1是程序计算的90%,TryGetValue被多次调用。所以,最好,我不想每次都打电话给锁。

1 个答案:

答案 0 :(得分:6)

如果任何机会在lock正在执行的同时在另一个线程上发生更新,则每次都必须TryGetValue

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

那就是说,锁可能并不可怕。你说TryGetValue被称为“很多次”,但你没说多久。更重要的是,你没有说你有多久会发生冲突。在现代硬件上,无竞争锁定会花费50纳秒的成本,因此它不是巨大的费用。您可以尝试锁定,看看它是如何执行的。您可能还会考虑ReaderWriterLockSlim

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