有很多关于ReaderWriterLockSlim类的文章,它允许多次读取和单次写入。所有这些(至少我发现的)告诉如何使用它而没有太多解释为什么以及如何工作。标准代码示例是:
lock.EnterUpgradeableReadLock();
try
{
if (test if write is required)
{
lock.EnterWriteLock();
try
{
change the resourse here.
}
finally
{
lock.ExitWriteLock();
}
}
}
finally
{
lock.ExitUpgradeableReadLock();
}
问题是:如果可升级锁仅允许单个线程进入其部分,为什么我应该在其中调用EnterWriteLock方法?如果我不这样做会怎样?或者如果不是使用EnterUpgradeableReadLock,我会调用EnterWriteLock并且在不使用可升级锁的情况下写入资源会发生什么?
答案 0 :(得分:10)
使用EnterUpgradeableReadLock
超过EnterReadLock
的好处是,您可以确定您检查的条件是否确定是否输入写入锁定在检查条件之间不会发生变化并实际进入写锁。这避免了常规lock
s:
if (whatever-condition)
{
lock (_lockObject)
{
// the condition may have changed betwen the check and the lock; verify
// that the condition is still valid
if (whatever-condition)
{
// do the stuff
}
}
}
同时,它不阻止对EnterReadLock
的调用,因此其他线程仍然可以在代码的其他部分获得读访问权(当然,这些调用将是阻止对EnterWriteLock
的调用,直到他们释放读锁定。)
答案 1 :(得分:3)
如果可升级锁只允许一个 单线程进入其部分, 为什么我应该调用EnterWriteLock 内的方法?
EnterWriteLock
将阻止只需要读取的其他线程 - 如果使用可升级锁,其他线程仍然可以获得读锁。来自EnterUpgradableLock
文档:
只有一个线程可以进入可升级版 在任何给定时间的模式。如果一个线程是 在可升级模式下,没有 线程等待进入写入模式, 任何数量的其他线程都可以进入 读取模式,即使有线程 等待进入可升级模式。
答案 2 :(得分:1)
ReaderWriterLockSlim类实质上包装了写锁,并允许所有读者只要不保持写锁就读。一旦写入锁定,读者就无法阅读。
EnterUpgradeableReadLock背后的想法只是允许程序员明确说明他们的意图而不是意外修改内容。
pm100 - 它更快,因为锁不是独占的,因为许多线程可以同时读取,这可以加速读取繁重的应用程序。实际上,如果您的应用程序写得很重,那么这可能不是最适合您的锁定解决方案。当很少进行修改但需要很多读取时,这种方法效果最好。