ReaderWriterLock类

  通常来讲,一个类型的实例对于并行的读操作是线程安全的,但是并行地更新操作则不是(并行地读和更新也不是)。 这对于资源也是一样的,比如一个文件。当保护类型的实例安全时,使用一个简单的排它锁即解决问题,但是当有很多的读操作而偶然的更新操作这就很不合理的限制了并发。一个例子就是这在一个业务程序服务器中,为了快速查找把数据缓存到静态字段中。 在这个方案中,ReaderWriterLock类被设计成提供最大容量的锁定。

  ReaderWriterLock为读和写的锁提供了不同的方法——AcquireReaderLock和AcquireWriterLock。两个方法都需要一个超时参数,并且在超时发生后抛出ApplicationException异常(不同于大多数线程类的返回false等效的方法)。超时发生相当容易在资源争用严重的时候。

  调用 ReleaseReaderLock或ReleaseWriterLock释放锁。 这些方法支持嵌套锁,ReleaseLock方法也支持一次清除所有嵌套级别的锁。(你可以随后调用RestoreLock类重新锁定相同的级别,它在ReleaseLock之前执行——如此来模仿Monitor.Wait的锁定切换行为)。

  你可以调用AcquireReaderLock开始一个read-lock ,然后通过UpgradeToWriterLock把它升级为write-lock。这个方法返回一个可能被用于调用DowngradeFromWriterLock的信息。这个方式允许读程序临时地请求写访问同时不必必须在降级之后重新排队列。

  在接下来的这个例子中,4个线程被启动:一个不停地往列表中增加项目;另一个不停地从列表中移除项目;其它两个不停地报告列表中项目的个数。前两者获得写的锁,后两者获得读的锁。每个锁的超时参数为10秒。(异常处理一般要使用来捕捉ApplicationException,这个例子中出于方便而省略了).

例子:

class Program
{
static ReaderWriterLock rw = new ReaderWriterLock ();
static List <int> items = new List <int> ();
static Random rand = new Random (); static void Main (string[] args)
{
new Thread (delegate() { while (true) AppendItem(); } ).Start();
new Thread (delegate() { while (true) RemoveItem(); } ).Start();
new Thread (delegate() { while (true) WriteTotal(); } ).Start();
new Thread (delegate() { while (true) WriteTotal(); } ).Start();
} static int GetRandNum (int max)
{ lock (rand) return rand.Next (max); } static void WriteTotal()
{
rw.AcquireReaderLock ();
int tot = ; foreach (int i in items) tot += i;
Console.WriteLine (tot);
rw.ReleaseReaderLock();
} static void AppendItem ()
{
rw.AcquireWriterLock ();
items.Add (GetRandNum ());
Thread.SpinWait ();
rw.ReleaseWriterLock();
} static void RemoveItem ()
{
rw.AcquireWriterLock ();
if (items.Count > )
items.RemoveAt (GetRandNum (items.Count));
rw.ReleaseWriterLock();
}
}

往List中加项目要比移除快一些,这个例子在AppendItem中包含了SpinWait来保持项目总数平衡。

按照请求到达的顺序,一共有四种 :
      Reader-Reader,第二个不需等待,直接获得读控制权; 
      Reader-Writer,第二个需要等待第一个调用ReleaseReaderLock()释放读控制权后,才能获得写控制权; 
      Writer-Writer,第二个需要等待第一个调用ReleaseWriterLock()释放写控制权后,才能获得写控制权; 
      Writer-Reader,第二个需要等待第一个调用ReleaseWriterLock()释放写控制权后,才能获得读控制权。

原文链接:http://www.cnblogs.com/coderzh/articles/1586268.html

【转】【Thread】ReaderWriterLock 读写锁的更多相关文章

  1. C# lock 语法糖实现原理--《.NET Core 底层入门》之自旋锁,互斥锁,混合锁,读写锁

    在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...

  2. C# lock的语法糖原理--《.net core 底层入门》之自旋锁,互斥锁,混合锁,读写锁

    在多线程环境中,多个线程可能会同时访问同一个资源,为了避免访问发生冲突,可以根据访问的复杂程度采取不同的措施 原子操作适用于简单的单个操作,无锁算法适用于相对简单的一连串操作,而线程锁适用于复杂的一连 ...

  3. java多线程-读写锁

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

  4. 让C#轻松实现读写锁分离

    ReaderWriterLockSlim 类 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问. 使用 ReaderWriterLockSlim 来保护由多个线程读取但每次只采用一 ...

  5. C#读写锁ReaderWriterLockSlim的使用

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对 ...

  6. 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...

  7. 用读写锁三句代码解决多线程并发写入文件 z

    C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...

  8. 锁的封装 读写锁、lock

    最近由于项目上面建议使用读写锁,而去除常见的lock锁.然后就按照需求封装了下锁.以简化锁的使用.但是开发C#的童鞋都知道lock关键字用起太方便了,但是lock关键字不支持超时处理.很无奈,为了实现 ...

  9. Java多线程13:读写锁和两种同步方式的对比

    读写锁ReentrantReadWriteLock概述 大型网站中很重要的一块内容就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务 ...

随机推荐

  1. C语言指针传递详解

    传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问,要在某个函数中修改数据,需要用指针传递数据,当数据是需要修改的指针的时候,就要传递指针的指针,传递参数(包括指针)的时候,传递 ...

  2. 【读书笔记】iOS-本地文件和数据安全注意事项

    一,程序文件的安全. 可通过将JavaScript源码时行混淆和加密,防止黑客轻易地阅读和篡改相关的逻辑,也可以防止自己的Web端与Native端的通讯协议泄露. 二,本地数据安全. 对于本地的重要数 ...

  3. 开始学习Oracle了

    开始学习Oracle了,加油 参考书Oracle开发实战经典,李兴华老师编著

  4. OC中代理的使用

    通常代理的使用需要以下几个步骤: 1.制定协议.协议可以在委托对象的.h中声明,也可以在单独的.h中声明.制定协议后,在协议中声明需要代理对象来实现的方法. 2.设置代理属性.制定协议后需要为委托对象 ...

  5. float类型转对象 对象转float类型(一)

    //float类型转化为对象CGFloat fValue = 1.f;NSNumber *objNo = [NSNumber numberWithFloat:fValue];数值.BOOL型都可以转成 ...

  6. Effective Java 18 Prefer interfaces to abstract classes

    Feature Interface Abstract class Defining a type that permits multiple implementations Y Y Permitted ...

  7. python基本数据结构-集合-方法

  8. 深入剖析jsonp跨域原理

    在项目中遇到一个jsonp跨域的问题,于是仔细的研究了一番jsonp跨域的原理.搞明白了一些以前不是很懂的地方,比如: 1)jsonp跨域只能是get请求,而不能是post请求: 2)jsonp跨域的 ...

  9. sql 执行动态语句

    没看明白,可不可以描述清楚点哦 收获园豆:5 回复 | artwl | 专家六级 |园豆:16486 | 2011-09-01 09:10 exec (select  top 2 * from pub ...

  10. 初识50个Linux命令

    1. [命令]:cat [功能说明]: concatenate files and print on the standard output #连接文件并打印到标准输出,有标准输出的都可以用重定向定向 ...