所以,我有一个 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/