C# ReaderWriterLockSlim类

194deeb394ef79c310f9fc9ee17f2ffb.png

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

33e3a20cf100cf483e21d7435163d2a1.png

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

bec12c13a9a1d5588a052f96b7363daa.png

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

dddbd9d2dbe1835967c258c82ab914d4.png

下面的示例程序创建了一个包含 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);}}

4105b7e7ee0c41bda04a81e678892ac1.png

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

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

1e3fd12b4f3a05d91ec8cd0f2a3773e2.png

bdb63dedcd6efa659a412846fb22f206.png

 微信公众号 

Dotnet讲堂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LOG4NET用法

log 4net组件下载:log4net.dll web.config配置如下&#xff1a; <?xml version"1.0" encoding"utf-8" ?> <configuration><configSections><section name"log4net" type"log4net.Config.Log4NetConfigurationSectio…

C# dataGridView控件实用属性及事件总结

一、属性 1.控制时间字段只显示“年-月-日”:dataGridView1.Columns[10].DefaultCellStyle.Format = "yyyy-MM-dd"; 2.背景颜色:dataGridView1.BackgroundColor = Color.Red; 3.列宽随内容自动调整:dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColu…

oracle log.xml分析,Oracle11g 中使用ADRCI 查看alert log文件(xml格式)

Automatic Diagnostic Repository (ADR)存放数据库诊断日志、跟踪文件的目录&#xff0c;称作ADR base&#xff0c;对应初始化参数diagnostic_dest。 如果设置了ORACLE_BASE环境变量&#xff0c;DIAGNOSTIC_DEST等于ORACLE_BASE&#xff0c;如果没有设置ORACLE_BASE&#xff0c…

怎么计算信息完整度_德阳冻货运镖怎么计算费用

德阳冻货运镖怎么计算费用物流”一词我们并不陌生&#xff0c;它把小到零食玩具、大到家用电器&#xff0c;一一送到我们手中&#xff0c;但传统的物流运输模式只能满足部分物品的运输要求。随着人们的生活品质不断提高、消费不断升级。德阳冻货运镖怎么计算费用息平台的支撑&a…

AI+时代,谈谈产品经理对图像识别技术的阈值控制

产品满足用户的需求有一个阈值&#xff0c;产品值低于阈值用户会觉得了无生趣&#xff0c;即产品一般般&#xff0c;也即产品经理做了功能经理。产品值等于阈值产品功能基本满足了用户的需求&#xff0c;而只有产品经理驾驭了需求&#xff0c;把产品做成作品&#xff0c;产品值…

利用html5看雪花飘落的效果

html5飘落的雪花堆积动画特效 <!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <title>下雪了&#xff0c;我们去堆雪人好吗&#xff1f; </title><base targe…

【亲身经验】如何在 6 个月内成为“微软 MVP”

前言很荣幸&#xff0c;在愚人节这天&#x1f601;&#xff0c;收到了获得“微软 MVP”奖项的通知&#xff1a;由于该奖项评选标准只涉及 2021 年所做的贡献&#xff0c;而我的贡献主要是公众号文章。因此以我从 2021/06 开始运营个人公众号算起&#xff0c;可以说&#xff0c;…

从listView1中选择记录到listView2中

1.自定义Worker字段类 public class SelectWorker{public int WorkerID;public string WkName;} 2.定义全局变量 List<SelectWorker> wkList0 = new List<SelectWorker>();List<SelectWorker> wkList1 = new List<SelectWorker>();List<SelectWorke…

3500个常用汉字表_小学常用560个汉字笔画笔顺表,打印下来,小学六年慢慢练...

温馨提示公众号改版后很多孩子及家长朋友找不到我们了为了方便大家更快地找到我们获取更多学习工具和资料您可以按照下面的方式 星标或置顶我们☟ ☟ ☟小学阶段&#xff0c;字写得好很重要&#xff0c;笔顺写对了也很重要。写对笔顺有利于把字写得美观&#xff0c;考试时碰到笔…

java之wait()、notify()实现非阻塞的生产者和消费者

一、对于wait()和notify()的解释 void notify()Wakes up a single thread that is waiting on this object’s monitor.唤醒等待获取锁资源的单个线程void notifyAll()Wakes up all threads that are waiting on this object’s monitor.唤醒等待获取锁资源的所有线程void wait…

大数据先行 传统金融转型需从体制上创新

经过几年发展&#xff0c;互联网金融成为金融行业一股鲜活的力量。同时&#xff0c;行业也意识到&#xff0c;这条鲶鱼不会在大众市场对银行构成威胁。日前&#xff0c;德勤的一份报告也指出&#xff0c;P2P的市场价值高达1800亿美元&#xff0c;但并没有在成本、风险和速度上对…

oracle存档模式,Oracle的备份和存档模式

Oracle的备份和存档模式在做硬件升级前必须要将数据库做一次全备份&#xff0c;以便在出现不可预料的情况下进行恢复&#xff0c;全备份的方法有多种&#xff0c;以下列举两种简单高效的逻辑备份和冷备份&#xff0c;在数据库可以宕机的条件下&#xff0c;推荐使用冷备份&#…

SVN安装和使用总结

SVN简介&#xff1a; 为什么要使用SVN&#xff1f; 程序员在编写程序的过程中&#xff0c;每个程序员都会生成很多不同的版本&#xff0c;这就需要程序员有效的管理代码&#xff0c;在需要的时候可以迅速&#xff0c;准确取出相应的版本。 Subversion是什么&#xff1f; 它是一…

从部署 httpd 入手,理清 k8s 配置中的 containerPort、port、nodePort、targetPort

注&#xff1a;文中各种内网、公网 IP 仅为示例&#xff0c;不保证所有 IP 都可以访问&#xff0c;且你的环境中 IP 可能不同。背景在上一篇文章 自己搭建一个k8s环境 中&#xff0c;我们一顿操作猛如虎&#xff0c;搭建出了由 1 个 master 和 1 个 worker 节点组成的 k8s 集群…

C#正则表达式判断输入的是不是数字

1.函数 public static bool IsFloat(string str){string regextext "^(-?\d)(\.\d)?$";Regex regex new Regex(regextext, RegexOptions.None);return regex.IsMatch(str.Trim());} 2.调用if (!IsFloat(textBox11.Text)){MessageBox.Show("应该是一个数字&q…

分享几个拉钩网的前端页面

http://c.lagou.com/allMarch/warmup/index.html?fromsinglemessage&isappinstalled0 http://c.lagou.com/careerism/invitation.html?fromgroupmessage&amp;isappinstalled0&scene4转载于:https://blog.51cto.com/snaile/1616398

Andorid之用ConditionVariable实现线程同步

一、学习ConditionVariable之前的复习 如果你不懂wait()、notify()怎么使用&#xff0c;最好先复习下我之前的这篇博客&#xff0c;怎么使用wait()、notify()实现生产者和消费者的关系 java之wait()、notify()实现非阻塞的生产者和消费者 二、看下ConditionVariable源代码实现…

360文件粉碎机_中山三乡资料文件销毁粉碎销毁资料文件公司一览表

中山三乡资料文件销毁粉碎销毁资料文件公司一览表安排搬运工作人员及运输车辆上门收取销毁物品&#xff0c;将需销毁的物品装上运输车辆&#xff0c;并进行拍照、车箱粘贴封条等工作。第五步&#xff1a;客户可安排工作人员&#xff0c;跟我公司销毁运输车辆一同前往我公司销毁…

Sonnedix收购意大利11.2MW光伏电站产品组合

2016年9月5日, 太阳能独立发电商Sonnedix宣布已经在意大利获得Trading Emissions 的11.2MW太阳能光伏电站产品组合&#xff0c;此交易预计将在2016年第四季度关闭。 该产品组合包括三个地面安装光伏电站: 阿布鲁佐的Basciano和Cupello、以及西西里岛的Librandello。 Sonnedix在…