C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步


  • 摘要:
    C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现如下功能:若是资源未被写操做锁定,那么任何线程均可对该资源进行读操做锁定,而且对读操做锁数量没有限制,即多个线程可同时对该资源进行读操做锁定,以读取数据。

  使用Monitor或Mutex进行同步控制的问题:因为独占访问模型不容许任何形式的并发访问,这样的效率老是不过高。许多时候,应用程序在访问资源时是进行读操做,写操做相对较少。为解决这一问题,C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现如下功能:若是资源未被写操做锁定,那么任何线程均可对该资源进行读操做锁定,而且对读操做锁数量没有限制,即多个线程可同时对该资源进行读操做锁定,以读取数据。若是资源未被添加任何读或写操做锁,那么一个且仅有一个线程可对该资源添加写操做锁定,以写入数据。简单的讲就是:读操做锁是共享锁,容许多个线程同时读取数据;写操做锁是独占锁,同一时刻,仅容许一个线程进行写操做。cookie

  示例代码以下:并发

using System;
using System.Threading;

namespace ProcessTest
{
class Program
{
//资源
static int theResource = 0;
//读、写操做锁
static ReaderWriterLock rwl = new ReaderWriterLock();

static void Main(string[] args)
{
//分别建立2个读操做线程,2个写操做线程,并启动
Thread tr0 = new Thread(new ThreadStart(Read));
Thread tr1 = new Thread(new ThreadStart(Read));
Thread tr2 = new Thread(new ThreadStart(Write));
Thread tr3 = new Thread(new ThreadStart(Write));

tr0.Start();
tr1.Start();
tr2.Start();
tr3.Start();

//等待线程执行完毕
tr0.Join();
tr1.Join();
tr2.Join();
tr3.Join();

System.Console.ReadKey();
}

//读数据
static void Read()
{
for (int i = 0; i < 3; i++)
{
try
{
//申请读操做锁,若是在1000ms内未获取读操做锁,则放弃
rwl.AcquireReaderLock(1000);
Console.WriteLine("开始读取数据,theResource = {0}", theResource);
Thread.Sleep(10);
Console.WriteLine("读取数据结束,theResource = {0}", theResource);
//释放读操做锁
rwl.ReleaseReaderLock();
}
catch (ApplicationException)
{
//获取读操做锁失败的处理
}
}
}

//写数据
static void Write()
{
for (int i = 0; i < 3; i++)
{
try
{
//申请写操做锁,若是在1000ms内未获取写操做锁,则放弃
rwl.AcquireWriterLock(1000);
Console.WriteLine("开始写数据,theResource = {0}", theResource);
//将theResource加1
theResource++;
Thread.Sleep(100);
Console.WriteLine("写数据结束,theResource = {0}", theResource);
//释放写操做锁
rwl.ReleaseWriterLock();
}
catch (ApplicationException)
{
//获取写操做锁失败
}
}
}
}
}

  上例中分别建立2个读取线程和2个写入线程,交替进行读、写操做。运行结果以下图:post

  观察运行结果,咱们很容易看出:读操做锁是共享锁,容许多个线程同时读取数据;写操做锁是独占锁,仅容许一个线程进行写操做。ui

  若是一个线程在获取读操做锁后,进行读操做的途中,但愿提高锁级别,将其变为写操做锁,能够调用ReaderWriterLock类的UpgradeToWriterLock(int timeOut)方法,该方法返回一个LockCookie值,该值保存了UpgradeToWriterLock方法调用前线程锁的状态。待写操做完成后,可调用DowngradeFromWriterLock(LockCookie lockcookie)方法,该方法根据传入的LockCookie参数值,将线程锁恢复到UpgradeToWriterLock方法调用前的状态。具体使用方法,你们能够查看MSDN以获取相关示例。spa

相关文章
相关标签/搜索