TryGetValue线程本身是否安全

Jay*_*Jay 2 c# dictionary thread-safety trygetvalue

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

我有一个主题:

void Thread1() {
  ...
  if (!Foo.TryGetValue(key, out v)) {
    Foo.Add(new VType());
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

唯一一次Foo被另一个线程访问是由a TryGetValue.

那么,我需要锁多少钱?我可以这样做:

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

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

Jim*_*hel 7

你必须lock每次如果有任何可以在另一个线程在同一时间出现一个更新的机会TryGetValue正在执行.

TryGetValue本身是线程安全的,因为多线程调用TryGetValue不会相互干扰.但是,如果任何线程调用Add而其他人正在使用字典执行任何其他操作,那么就存在腐败的可能性.

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

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