Проблемы .NET ReaderWriterLockSlim - PullRequest
6 голосов
/ 22 марта 2010

Много написано о классе 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 и запишу ресурс без использования обновляемой блокировки вообще?

Ответы [ 3 ]

10 голосов
/ 22 марта 2010

Преимущество использования 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 до тех пор, пока они не снимают блокировки чтения).

3 голосов
/ 22 марта 2010

, если обновляемая блокировка позволяет только одному потоку войти в его раздел, почему я должен вызывать метод EnterWriteLock в?Вы используете обновляемую блокировку, другие потоки могут все еще получить блокировки чтения.Из документации EnterUpgradableLock:

Только один поток может перейти в режим обновления в любой момент времени.Если поток находится в режиме обновления и нет потоков, ожидающих перехода в режим записи, любое количество других потоков может перейти в режим чтения, даже если есть потоки, ожидающие перехода в режим обновления.

1 голос
/ 22 марта 2010

Класс ReaderWriterLockSlim обертывает блокировку записи и позволяет всем читателям читать, пока блокировка записи не удерживается.Как только блокировка записи удерживается, читатели не могут читать.

Идея, лежащая в основе EnterUpgradeableReadLock, заключается в том, чтобы просто позволить программисту явно заявить о своем намерении и не случайно изменить материал.потому что блокировка не исключительна, так как многие потоки могут читать одновременно, что может ускорить чтение тяжелых приложений.На самом деле, если ваше приложение требует интенсивной записи, это может быть не лучшим решением для блокировки.Это работает лучше всего, когда изменения делаются редко, но требуется много чтений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...