为了使锁定机制允许锁定多个读取器(而不是一个写入器)访问某个资源,可以使用 ReaderWriterLockSlim 类。这个类提供了一个锁定功能,如果没有写入器锁定资源,就允许多个读取器访问资源,但只能有一个写入器锁定该资源。

ReaderWriterLockSlim 类有阻塞或不阻塞的方法来获取读取锁,如阻塞的EnterReadLock() 和不阻塞的 TryEnterReadLock() 方法,还可以使用阻塞的EnterWriteLock() 和不阻塞的 TryEnterWriteLock() 方法获得写入锁定。如果任务先读取资源,之后写入资源,它就可以使用 EnterUpgradableReadLock() 或 TryEnterUpgradableReadLock() 方法获得可升级的读取锁定。有了这个锁定,就可以获得写入锁定,而不需要释放读取锁定。

这个类的几个属性提供了当前锁定的相关信息。如CurrentReadCount、WaitingReadCount、WaitingUpgradableReadCount 和 WaitingWriteCount。

下面的示例程序创建了一个包含 6 项的集合和一个 ReaderWriterLockSlim() 对象。ReaderMethod() 方法获得一个读取锁定,读取列表中的所有项,并把它们写到控制台中。WriterMethod(0 方法试图获得一个写入锁定,以改变集合的所有值。在Main()方法中,启动6个任务,以调用 ReaderMethod()或WriterMethod()方法。

class Program
{private static List<int> _items = new List<int>() { 0,1,2,3,4,5}; private static ReaderWriterLockSlim _rwl =new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);public static void ReaderMethod(object reader)
{try{_rwl.EnterReadLock();For (int i = 0; i < _items.Count; i++){Console.WriteLine($"reader {reader}, loop: {i}, item: {_items[i]}"); Task.Delay(40).Wait();}}finally{_rwl.ExitReadLock();}}public static void WriterMethod(object writer)
{try{while (!_rwl.TryEnterWriteLock(50)){Console.WriteLine($"Writer {writer} waiting for the write lock"); Console.WriteLine($"current reader count:(_rwl.CurrentReadCount}");}Console.WriteLine($"Writer {writer) acquired the lock");for (int i = 0; i < _items.Count; i++){_items[i]++;Task.Delay(50).Wait();}Console.WriteLine($"Writer {writer} finished");}finally{_rwl.ExitWriteLock();}}static void Main()
{var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning,TaskContinuationOptions.None); var tasks = new Task[6];tasks[0] = taskFactory.StartNew(WriterMethod, 1); tasks[1] = taskFactory.StartNew(ReaderMethod, 1);tasks[2] = taskFactory.StartNew(ReaderMethod, 2);tasks[3] = taskFactory.StartNew(WriterMethod, 2);tasks[4] = taskFactory.StartNew(ReaderMethod, 3); tasks[5] = taskFactory.StartNew(ReaderMethod, 4); Task.WaitAll(tasks);}}

运行这个应用程序,可以看到第一个写入器先获得锁定。第二个写入器和所有的读取器需要等待。接着,读取器可以同时工作,而第二个写入器仍在等待资源。

Writer 1 acquired the lock
Writer 2 waiting for the write lock
current reader count: 0
Writer 2 waiting for the write lock
current reader count: 0
Writer 2 waiting for the write lock
current reader count: 0
Writer 2 waiting for the write lock
current reader count: 0
Writer 1 finished
reader 4, loop: 0,item: 1
reader 1, loop: 0, item: 1
Writer 2 waiting for the write lock
current reader count: 4
reader 2, loop: 0,item: 1
reader 3, loop: 0, item: 1
reader 4,loop: 1, item: 2
reader 1, loop: 1, item: 2
reader 3, loop: 1,item: 2
reader 2, loop: 1, item: 2
Writer 2 waiting for the write lock
current reader count: 4
reader 4, loop: 2, item: 3
reader l, loop: 2,item: 3
reader 2, loop: 2,item: 3
reader 3, loop: 2, item: 3
Writer 2 waiting for the write lock
current reader count: 4
reader 4, loop: 3, item: 4
reader 1, loop: 3,item: 4
reader 2, loop: 3, item: 4
reader 3, loop: 3, item: 4
reader 4, loop: 4, item: 5
reader 1, loop: 4, item: 5
Writer 2 waiting for the write lock
current reader count: 4
reader 2, loop: 4, item: 5
reader 3, loop: 4, item: 5
reader 4, loop: 5, item: 6
reader 1,loop: 5,item: 6
reader 2, loop: 5, item: 6
reader 3, loop: 5, item: 6
Writer 2 waiting for the write lock
current reader count: 4
Writer 2 acquired the lock
Writer 2 finished

 微信公众号 

Dotnet讲堂

C# ReaderWriterLockSlim类相关推荐

  1. C#多线程编程实战(二):线程同步

    2.1 简介 竞争条件:多个线程同时使用共享对象.需要同步这些线程使得共享对象的操作能够以正确的顺序执行 线程同步问题:多线程的执行并没有正确的同步,当一个线程执行递增和递减操作时,其他线程需要依次等 ...

  2. 【译】最大限度地降低多线程 C# 代码的复杂性

    [译]最大限度地降低多线程 C# 代码的复杂性 原文:[译]最大限度地降低多线程 C# 代码的复杂性 分支或多线程编程是编程时最难最对的事情之一.这是由于它们的并行性质所致,即要求采用与使用单线程的线 ...

  3. C# 多线程并发锁模式-总结

    开篇: 互斥还是lock Monitor Mutex 模式! Muex Monitor lock AutoEventSet ManualEventSet 后续的 ReaderWriterLock Re ...

  4. C#中的线程(三) 使用多线程

    第三部分:使用多线程 1.  单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM--Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留 ...

  5. .NET Core用数据库做配置中心加载Configuration

    本文介绍了一个在.NET中用数据库做配置中心服务器的方式,介绍了读取配置的开源自定义ConfigurationProvider,并且讲解了主要实现原理. 1. 为什么用数据库做配置中心 在开发youz ...

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

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

  7. 持续畅销20年的《C#高级编程》出第11版了!

    TA是谁? Wrox精品红皮书, 引领无数程序员进入程序开发殿堂, C#专家级指南, 是经验丰富的程序员提高效率的更快捷方式,   连续畅销20年,累计销量超30万册. TA出生名门:  TA战绩辉煌 ...

  8. 最大限度地降低多线程 C# 代码的复杂性

    分支或多线程编程是编程时最难最对的事情之一.这是由于它们的并行性质所致,即要求采用与使用单线程的线性编程完全不同的思维模式.对于这个问题,恰当类比就是抛接杂耍表演者,必须在空中抛接多个球,而不要让它们 ...

  9. c#多线程总结(纯干货)

    线程基础 创建线程 static void Main(string[] args) {Thread t = new Thread(PrintNumbers);t.Start();//线程开始执行Pri ...

最新文章

  1. 神经网络的迭代次数和收敛误差与谐振子的位移和时间
  2. 图灵原版计算机科学系列,图灵原版计算科学系列
  3. Centos7下搭建LAMP环境,安装wordpress(不会生产博客,只是一名博客搬运工)(菜鸟)
  4. C ++ STL中的set :: lower_bound()函数
  5. Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法
  6. (23)css3文字阴影text-shadow
  7. ORACLE取周、月、季、年的開始时间和结束时间
  8. ie版本过低提示升级ie的示例
  9. JSP编程,url中加斜杠和不加斜杠的区别
  10. 树莓派基础实验13:雨滴探测传感器实验
  11. 火狐不支持css图标,火狐浏览器不支持css缩放样式:zoom,如何完美解决?
  12. 国外统计学课程主页Statistical Books, Manuals and Journals
  13. Unity获取真实地理地图应用Terrain笔记
  14. httpclient
  15. windows7 下安装 kali Linux 双系统
  16. 【OpenCV入门教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
  17. Python基础入门第二课--Python编辑器的选择
  18. tab吸顶功能实现,css实现沾性吸顶,sticky实现吸顶,解决sticky吸顶失效
  19. TF实战QA丨这个问题,我以前也遇到过
  20. 轻松实现即席查询,Smartbi满足用户多样分析需求

热门文章

  1. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录
  2. nginx连接uwsgi使用web.py框架构造pythonweb项目
  3. MFC中的文件读写技术
  4. FileInfo.LastWriteTime和FileInfo.LastAccessTime的值不是准确的
  5. Yahoo网站性能最佳体验的34条黄金守则
  6. SQL中的left outer join,inner join,right outer join用法 (左右内连接)
  7. Arts 第十九周(7/22 ~ 7/28)
  8. robotframework(12)修改用户密码(从数据库查询短信验证码)
  9. [USACO13JAN] Cow Lineup (单调队列,尺取法)
  10. MVC中提交表单的4种方式