所以,我有一个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被多次调用。所以,最好不要每次都调用lock。
发布于 2013-06-05 08:02:21
如果在执行TryGetValue的同时有可能在另一个线程上发生更新,那么每次都必须执行lock。
TryGetValue本身是线程安全的,因为调用TryGetValue的多个线程不会相互干扰。但是,如果任何线程调用Add,而其他线程正在对字典执行任何其他操作,则存在损坏的可能性。
也就是说,锁可能并不可怕。您说TryGetValue被调用了“很多次”,但是您没有说有多频繁。更重要的是,你没有说你可能会有多频繁的冲突。在现代硬件上,一个非争用锁将花费大约50纳秒,所以这不是一个巨大的开销。您可以尝试这个锁,看看它的性能如何。您也可以考虑使用ReaderWriterLockSlim。
尽管读取操作是以无锁的方式完成的,但理解ConcurrentDictionary并不是无锁的数据结构,这一点很重要。它可能会在您的情况下表现得更好(可能会),但这不是给定的。
https://stackoverflow.com/questions/16929231
复制相似问题