Introduction

ReaderWriterLockSlim class is new to .Net Framework 3.5 and is a replacement for the older ReaderWriterLock class.

Problem with ReaderWriterLock

The problem with ReaderWriterLock is with its implementation. Several experts have slammed this technique and found that outside of limited scenarios, it is actually far slower than the Monitor.Enter method used to get an exclusive lock. ReaderWriterLock gives higher priority to reader threads than writers. This makes sense if you have many readers and only a few writers. So a lot of readers are able to read the resource while the writer has to wait longer to get the lock. But what If you have equal or more writers. The process of favoring readers make writer threads queued up and take a very long time to complete.

To solve all issues related to the ReaderWriterLock class, the .Net Framework 3.5 introduces the new class ReaderWriterLockSlim.

ReaderWriterLockSlim class

Namespace: System.Threading

This namespace provides all methods and properties the class needs to implement the ReaderWriterLockSlim class.

Assembly: System.Core (in System.Core.dll)

Constructors

Properties

Method

ReaderWriterLockSlim is used to protect a resource which is read by multiple threads and written to by one thread at a time. ReaderWriterLockSlim allows multiple threads to be in read mode, allows one thread to be in write mode with exclusive ownership of the lock, and allows one thread that has read access to be in upgradeable read mode, from which the thread can upgrade to write mode without having to relinquish its read access to the resource.

A thread can enter the lock in three modes.

and has the methods EnterReadLock, EnterWriteLock,EnterUpgradeableReadLock, and corresponding TryEnterXXLock and ExitXXLock methods, that do what you'd expect. Read and Write are easy and should be familiar: Read is a typical shared lock mode, where any number of threads can acquire the lock in the Read mode simultaneously, and Write is a mutual exclusion mode, where no other threads are permitted to simultaneously hold the lock in any mode. The UpgradeableReadLock will probably be new to most people, though it's a concept that's well known to database folks, and is the magic that allows us to fix the upgrade problem I mentioned earlier. We'll look at it more closely in a moment.

To use the ReaderWriterLockSlim, it's a simple matter of creating a lock for your class.

ReaderWriterLockSlim rwls = new ReaderWriterLockSlim();

and then wrapping all read or write operations between Enter{Read,Write}Lock and Exit{Read,Write}Lock methods.

private void ReadTest()

{

m_Lock.EnterReadLock();

// access the shared state for reading here

m_Lock.ExitReadLock();

}

private void WriteTest()

{

m_Lock.EnterWriteLock();

// access the shared state for writing here

m_Lock.ExitWriteLock();

}

In the following code, three threads continually enumerate a list, while two further threads append a random number to the list every second. A read lock protects the list readers and a write lock protects the list writers:

using System;
using System.Collections.Generic;
using System.Threading;
namespace ReaderWriterLockSlim_class
{
class akshay
{
static ReaderWriterLockSlim rw = new ReaderWriterLockSlim();
static List<int> items = new List<int>();
static Random rand = new Random();
static void Main()
{
new Thread(Read).Start();
new Thread(Read).Start();
new Thread(Read).Start();
new Thread(Write).Start("A");
new Thread(Write).Start("B");
Console.Read();
}
static void Read()
{
while (true)
{
rw.EnterReadLock();
foreach (int i in items) Thread.Sleep(10);
rw.ExitReadLock();
}
}
static void Write(object threadID)
{
while (true)
{
int newNumber = GetRandNum(50);
rw.EnterWriteLock();
items.Add(newNumber);
rw.ExitWriteLock();
Console.WriteLine("Thread " + threadID + " added " + newNumber);
Thread.Sleep(100);
}
}
static int GetRandNum(int max)
{
lock (rand)
return rand.Next(max);
}
}
}

Output

img1.gif


ReaderWriterLockSlim
has managed thread affinity; that is, each Thread object must make its own method calls to enter and exit lock modes. No thread can change the mode of another thread.

Resources

Here some useful related resources.