views:

123

answers:

4

There are lots written about the ReaderWriterLockSlim class which allows multiple read and a single write. All of these (at least that I had found) tell how to use it without much explanation why and how it works. The standard code sample is:

lock.EnterUpgradeableReadLock();

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

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

The question is: if upgradeable lock permits only a single thread to enter its section, why I should call EnterWriteLock method within? What will happen if I don't? Or what will happen if instead of EnterUpgradeableReadLock I will call EnterWriteLock and will write to a resource without using upgradeable lock at all?

A: 

I found that part of my team had implemented RW Locks (in .net). I asked why and they said it was faster, I asked by how much and the said they did not know. "SO how do you know it is faster then?" "Well it has to be faster doesn't it! I mean, people sometimes dont have to wait. "

So we wrote a test and guess what - plain old fashioned locks were faster. Only optimize when you know you have a problem

pm100
+1  A: 

The ReaderWriterLockSlim class essentially wrappers the write lock and allows all readers to read so long as the write lock isnt held. Once the write lock is held no readers can read.

The idea behind the EnterUpgradeableReadLock is simply to allow the programmer to explicitly state their intention and not accidentally modify stuff.

pm100 - it is faster because a lock isn't exclusive as many threads can read at once which can speed up read heavy apps. In fact if your application is write heavy then this might not be the best locking solution for you. This works best when modifications are rarely made but many reads are required.

Chris
You say that the EnterUpgradeableReadLock is for explicitness only and theoretically can be replaced by EnterWriteLock?
Kamarey
Internally. If you just use EnterWriteLock then it will block any readers so it is not good to do this.
Chris
+2  A: 

if upgradeable lock permits only a single thread to enter its section, why I should call EnterWriteLock method within?

EnterWriteLock would block other threads that only need to read - if you use an upgradable lock, other threads can still get read locks. From the EnterUpgradableLock documentation:

Only one thread can enter upgradeable mode at any given time. If a thread is in upgradeable mode, and there are no threads waiting to enter write mode, any number of other threads can enter read mode, even if there are threads waiting to enter upgradeable mode.

Jeff Sternal
Doesn't EnterUpgradeableReadLock also block all threads until it exits?
Kamarey
Nope, I'll update my answer with the relevant part of the documentation.
Jeff Sternal
+3  A: 

The upside of using EnterUpgradeableReadLock over EnterReadLock is that you can know for sure that the condition that you check in order to determine whether to enter the write lock or not does not change between checking the condition and actually entering the write lock. This avoids the duplication that may be needed with regular 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
        }
    }
}

At the same time, it does not block calls to EnterReadLock, so other threads may still get read access in other parts of the code (and those calls will, of course, block the call to EnterWriteLock until they release the read locks).

Fredrik Mörk
Thanks to all! As I can accept a single answer, I chose (subjectively) this one as most informative.
Kamarey