【问题标题】:.NET ReaderWriterLockSlim issues.NET ReaderWriterLockSlim 问题
【发布时间】:2010-03-22 16:49:33
【问题描述】:

有很多关于 ReaderWriterLockSlim 类的文章,它允许多次读取和一次写入。所有这些(至少是我发现的)都告诉了如何使用它,而没有太多解释它为什么以及如何工作。标准代码示例是:

lock.EnterUpgradeableReadLock();

try
{
   if (test if write is required)
   {
      lock.EnterWriteLock();

      try
      {
          change the resourse here.
      }
      finally
      {
         lock.ExitWriteLock();
      }
   }
}
finally
{
   lock.ExitUpgradeableReadLock();
}

问题是:如果可升级锁只允许单个线程进入它的部分,我为什么要在其中调用 EnterWriteLock 方法?如果我不这样做会怎样?或者,如果我调用 EnterWriteLock 而不是使用 EnterUpgradeableReadLock 并在完全不使用可升级锁的情况下写入资源,会发生什么?

【问题讨论】:

    标签: .net multithreading thread-safety


    【解决方案1】:

    使用EnterUpgradeableReadLock 而不是EnterReadLock 的好处是,您可以确定您检查的条件以确定是否进入写锁,在检查条件和实际进入写锁之间不会发生变化。写锁。这避免了常规locks 可能需要的重复:

    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,直到他们释放读锁)。

    【讨论】:

    • 谢谢大家!由于我可以接受一个答案,因此我(主观地)选择了这个答案最为丰富。
    【解决方案2】:

    如果可升级锁只允许 单线程进入其部分, 为什么我应该调用 EnterWriteLock 方法内?

    EnterWriteLock 会阻塞其他只需要读取的线程 - 如果您使用可升级锁,其他线程仍然可以获得读取锁。来自EnterUpgradableLock 文档:

    只有一个线程可以进入可升级 在任何给定时间模式。如果一个线程是 在可升级模式下,并且没有 等待进入写入模式的线程, 任何数量的其他线程都可以进入 读取模式,即使有线程 等待进入可升级模式。

    【讨论】:

    • EnterUpgradeableReadLock 不也阻塞所有线程,直到它退出?
    • 不,我将使用文档的相关部分更新我的答案。
    【解决方案3】:

    ReaderWriterLockSlim 类本质上包装了写锁,并允许所有读者在写锁未持有的情况下进行读取。一旦持有写锁,就没有读者可以读取。

    EnterUpgradeableReadLock 背后的想法只是让程序员明确说明他们的意图,而不是意外修改内容。

    pm100 - 它更快,因为锁不是独占的,因为许多线程可以一次读取,这可以加快读取繁重应用程序的速度。事实上,如果您的应用程序编写繁重,那么这可能不是您最好的锁定解决方案。这在很少进行修改但需要多次读取时效果最佳。

    【讨论】:

    • 你说EnterUpgradeableReadLock只是为了显式,理论上可以用EnterWriteLock代替?
    • 内部。如果你只是使用 EnterWriteLock,那么它会阻止任何读者,所以这样做不好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多