ReaderWriterLock 用於同步存取資源。

它能在任何指定時間並行讀取多重執行緒或寫入單一執行緒。 如果資源不常變更,ReaderWriterLock 的產量優於每次一的鎖定 (例如 Monitor)。

如果不常寫入 (而且寫入時間很短) 而是以讀取為主,則 ReaderWriterLock 最適合。 多重讀取器和單一寫入器交替,就不會長期鎖定讀取器和寫入器。

    長期保留讀取器鎖定或寫入器鎖定,會影響其他執行緒。 為獲得最佳效能,您不妨考慮重組應用程式將寫入期間縮至最小。

執行緒可以保留讀取器鎖定或寫入器鎖定,但不能同時執行。

與其釋放讀取器鎖定取得寫入器鎖定,您不妨使用 UpgradeToWriterLock 和 DowngradeFromWriterLock。

遞迴鎖定要求會增加鎖定上的鎖定計數。

讀取器和寫入器是個別佇列。 執行緒釋放寫入器鎖定時,在讀取器佇列中等候的所有執行緒都會獲得讀取器鎖定;釋放所有讀取器鎖定時,在寫入器佇列中等候的下一個執行緒 (若有) 會獲得寫入器鎖定,以此類推。 換言之,ReaderWriterLock 在讀取器集合和寫入器集合之間交替。

寫入器佇列中的執行緒正在等候釋放讀取器鎖定時,要求新讀取器鎖定的執行緒也不斷在讀取器佇列中累積。 即使這些要求可以和現有讀取器鎖定的持有人共用並行存取,卻仍然不會同意這些要求;此一措施可以協助避免讀取器持續鎖定寫入器的情況。

大部分取得鎖定 ReaderWriterLock 的方法會接受逾時值。 逾時可用來避免應用程式鎖死。 例如,執行緒可能在一個資源上取得寫入器鎖定,並在第二個資源上取得讀取器鎖定;同時可能有另一個執行緒在第二個資源上取得寫入器鎖定,並在第一個資源上取得讀取器鎖定。 此時除非使用逾時,否則執行緒會鎖死。

如果逾時間隔到期但鎖定要求並未獲准,這個方法會擲回 ApplicationException,將控制項傳回至呼叫執行緒。 執行緒可以攔截這個例外狀況,並決定下一個採取動作。

逾時值是以毫秒為單位。 如果您使用 System.TimeSpan 指定逾時,則會使用 TimeSpan 表示的毫秒總整數。 下表顯示有效的逾時值 (以毫秒為單位)。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
//读线程锁
static ReaderWriterLock m_ReadLock =new ReaderWriterLock();
static ReaderWriterLock m_WriteLock =new ReaderWriterLock();
//资源
staticint m_nResource =0;

//读取资源线程
staticvoid ReadProc()
{
for (int i =0; i <5; i++)
{
ReadResource(5000);
Thread.Sleep(500);
}
}

//写入资源线程
staticvoid WriteProc()
{
for (int i =0; i <5; i++)
{
WriteResource(5000);
Thread.Sleep(500);
}
}

//读取资源
privatestaticbool ReadResource(int timeout)
{
try
{
m_ReadLock.AcquireReaderLock(timeout);
try
{
Console.WriteLine("成功获得读线程锁, 资源值:{0}", m_nResource);
}
finally
{
m_ReadLock.ReleaseReaderLock();
}
}
catch (ApplicationException ex)
{
Console.WriteLine("获取锁超时:{0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("获取锁异常:{0}", ex.Message);
}
returntrue;
}

//写入资源
privatestaticbool WriteResource(int timeout)
{
try
{
m_WriteLock.AcquireWriterLock(timeout);
try
{
Console.WriteLine("成功获得写线程锁, 资源值:{0}", m_nResource);
m_nResource++;
Console.WriteLine("写入资源 {0}", m_nResource);
}
finally
{
m_WriteLock.ReleaseWriterLock();
}
}
catch (ApplicationException ex)
{
Console.WriteLine("获取锁超时:{0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("获取锁异常:{0}", ex.Message);
}
returntrue;
}

staticvoid Main(string[] args)
{
Thread t1 =new Thread(new ThreadStart(ReadProc));
Thread t2 =new Thread(new ThreadStart(WriteProc));
t1.Start();
t2.Start();

Thread.Sleep(5000);
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
}
}

转载于:https://www.cnblogs.com/LinFx/archive/2011/07/07/2123674.html

C# 读写锁 ReaderWriteLock相关推荐

  1. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)

    前言 本文对Java的一些锁的概念和实现做个整理,涉及:公平锁和非公平锁.可重入锁(又名递归锁).自旋锁.独占锁(写)/共享锁(读)/互斥锁.读写锁 公平锁和非公平锁 概念 公平锁是指多个线程按照申请 ...

  2. ReentrantReadWriteLock读写锁的使用

    Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. 读写锁:分为读 ...

  3. golang:1.并发编程之互斥锁、读写锁详解

    本文转载自junjie,而后稍作修改. 一.互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段.它由标准库代码包sync中的Mutex结构体类型代表.sync.Mutex类型(确切地说,是 ...

  4. Linux多线程的同步------读写锁

    前面介绍过Linux多线程同步的另外两个方法------互斥锁和信号量 Linux多线程的同步-----信号量和互斥锁_神厨小福贵!的博客-CSDN博客 下面来看一下读写锁: 读写锁和互斥锁都带有一个 ...

  5. 互斥量、读写锁长占时分析的利器——valgrind的DRD

    在进行多线程编程时,我们可能会存在同时操作(读.写)同一份内存的可能性.为了保证数据的正确性,我们往往会使用互斥量.读写锁等同步方法.(转载请指明出于breaksoftware的csdn博客) 互斥量 ...

  6. Linux多线程实践(6) --Posix读写锁解决读者写者问题

    Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restr ...

  7. ReentrantReadWriteLock(读写锁)

    为了提高性能,java提供了读写锁, 读锁: 在读的地方使用读锁,可以多个线程同时读. 写锁: 在写的地方使用写锁,只要有一个线程在写,其他线程就必须等待 例子: public static Read ...

  8. Java并发- 读写锁中的性能之王:StampedLock

    为什么StampedLock这么神奇?能够达到这种效果,它的核心思想在于,在读的时候如果发生了写,应该通过重试的方式来获取新的值,而不应该阻塞写操作.这种模式也就是典型的无锁编程思想,和CAS自旋的思 ...

  9. 嵌入式 自旋锁、互斥锁、读写锁、递归锁

    互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁,通常情况下锁操作失败会将该线程 ...

  10. ReentrantReadWriteLock读写锁及其在 RxCache 中的使用

    一. ReentrantReadWriteLock读写锁 Lock 是相当于 synchronized 更面向对象的同步方式,ReentrantLock 是 Lock 的实现. 本文要介绍的 Reen ...

最新文章

  1. 网站收录的提升离不开“方法”和“坚持”
  2. Python: Convert rst to html
  3. saltstack部署java应用失败无日志——CICD 部署
  4. 80386/386/Intel386 架构/流水线及其优化
  5. webpack 打包第三方库_Webpack 打包第三方代码库
  6. css用边框实现圆角矩形
  7. C++关键字 friend
  8. Winform中自定义xml配置文件后对节点进行读取与写入(XmlDocument)
  9. IP数据包格式各字段详解说明
  10. 计算机考研909考试大纲,山东大学2019年909数据结构考研大纲
  11. 正六边形:判断点是否在正六边形内
  12. 提高你计算机科学知识的5本书
  13. 必备的Word软件应用技巧
  14. Linux修改hosts
  15. 简历制作要点与面试技巧
  16. RGB和RGBA之间的转换 (实用、赞)
  17. 十七、Origin绘制散点图
  18. 全志A40i+Logos FPGA开发板(4核ARM Cortex-A7)硬件说明书(上)
  19. 关于物模型的一些理解和总结
  20. 解决联想拯救者混合模式+不插电情况下屏幕亮度和颜色异常问题

热门文章

  1. php ajax 返回字符串而不是对象
  2. js中定义变量的符号
  3. docker tag 镜像id_手摸手带你 Docker 从入门到实践
  4. 电气计算机基础知识,电气基础知识
  5. 在页面中 js 获取光标/鼠标的坐标,获取光标的的像素坐标
  6. 计算机大学毕业好考公务员,哪些大学的毕业生更容易考上公务员?
  7. 瀚云平台kafka简单原理
  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_02 递归_4_练习_递归打印多级目录...
  9. 源码:Java集合源码之:哈希表(二)
  10. linux(ubuntu) 搭建java程序运行环境