使用 ReaderWriterLockSlim
时是否需要双重检查锁模式?
考虑这个场景:我有一个字典
。东西可以加进去。但是东西不能从里面去掉。添加东西时,就时间而言,这可能是一个非常昂贵的操作(只有数百毫秒,但相对于应用程序的其余部分来说仍然很昂贵)如果我想添加一些东西但它还不存在,是否会有任何获得的东西:
- 首先获取读锁,然后检查是否存在,
- 然后进入可升级的读锁,再次检查,
- 然后如果该项目仍然不在字典中则进入写锁定?
类似下面的内容:
void populateIfNotPresent( object thing )
{
_lock.EnterReadLock( ) ;
bool there = _dictionary.ContainsKey(thing);
_lock.ExitReadLock( ) ;
// Remember, the specs say nothing can be removed from this dictionary.
if (!there)
{
_lock.EnterUpgradeableReadLock( ) ;
try
{
if( !_dictionary.ContainsKey( thing ) )
{
_lock.EnterWriteLock( ) ;
try
{
populate( thing ) ;
}
finally
{
_lock.ExitWriteLock( ) ;
}
}
}
finally
{
_lock.ExitUpgradeableReadLock( ) ;
}
}
}
文档说一次只有一个线程可以进入可升级的读锁,但不会阻止任何其他线程进入读锁,所以看起来有值(value)在双检查锁。
你怎么看?这是矫枉过正吗?
最佳答案
ReaderWriterLockSlim
class (与任何其他读写器锁一样)与写入次数相比意味着大量读取。
你所做的实际上是三重检查,这是多余的;您不妨输入一个不可分级的写锁。如果该项存在,则退出锁,否则升级为写锁。
您的方法表明读取在这里没有提供任何值(value),因为您很有可能执行写入。由于可升级写入不会阻止任何其他读取,因此它不应该在这里杀死你。
但是,如果这是您进行读/写操作的唯一地方(或者大部分发生在这里),那么就有问题了,您的读/写比率不够高保证读/写锁,你应该看看其他一些同步方法。
也就是说,说到底,一切都是为了测试性能;如果你要优化一个实现,你需要测量它的当前性能以便进行比较,否则,它只是 premature optimization .
关于.net - Double Check Lock 模式应该与 ReaderWriterLockSlim 一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6947499/