C# ReaderWriterLock类学习

news2024/11/27 14:49:30

前言

今天这篇文章我们来学习一下ReaderWriterLock类,ReaderWriterLock类定义了实现单写程序和多读程序语义的锁。这个类主要用于文件操作,即多个线程可以读取文件,但只能用一个线程来更新文件。使用ReaderWriterLock类时,任意数量的线程都可以同时安全地读取数据。只有当线程进行更新时,数据才被锁定。只有在没有占用锁的写程序线程时,读程序线程才能获得锁。只有在没有占用锁的读程序或者写程序线程时,写程序线程才能获得锁。

12354689123110.gif

ReaderWriterLock类概念

ReaderWriterLock 用于同步对资源的访问。在任何给定时间,它都允许对多个线程进行并发读取访问,或允许对单个线程进行写入访问。 在资源不频繁更改的情况下,提供 ReaderWriterLock 比简单的一次性锁(例如 Monitor)更好的吞吐量。ReaderWriterLock 在大多数访问是读取的最好位置,而写入频率不常且持续时间较短。 多个读取器与单个编写器交替,这样读者和编写器都不会长期被阻止

C# (2).png

ReaderWriterLock类方法和属性

构造函数
ReaderWriterLock()
初始化 ReaderWriterLock 类的新实例。

属性
IsReaderLockHeld
获取一个值,该值指示当前线程是否持有读线程锁。
IsWriterLockHeld
获取一个值,该值指示当前线程是否持有写线程锁。
WriterSeqNum
获取当前序列号。

方法
AcquireReaderLock(Int32)
使用一个 Int32 超时值获取读线程锁。
AcquireReaderLock(TimeSpan)
使用一个 TimeSpan 超时值获取读线程锁。
AcquireWriterLock(Int32)
使用一个 Int32 超时值获取写线程锁。
AcquireWriterLock(TimeSpan)
使用一个 TimeSpan 超时值获取写线程锁
AnyWritersSince(Int32)
指示获取序列号之后是否已将写线程锁授予某个线程。
DowngradeFromWriterLock(LockCookie)
将线程的锁状态还原为调用 UpgradeToWriterLock(Int32) 前的状态。
Equals(Object)
确定指定对象是否等于当前对象。(继承自 Object)
Finalize()
确保垃圾回收器回收 ReaderWriterLock 对象时释放资源并执行其他清理操作。
GetHashCode()
作为默认哈希函数。(继承自 Object)
GetType()
获取当前实例的 Type。(继承自 Object)
MemberwiseClone()
创建当前 Object 的浅表副本。(继承自 Object)
ReleaseLock()
释放锁,不管线程获取锁的次数如何。
ReleaseReaderLock()
减少锁计数。
ReleaseWriterLock()
减少写线程锁上的锁计数。
RestoreLock(LockCookie)
将线程的锁状态还原为调用 ReleaseLock() 前的状态。
ToString()
返回表示当前对象的字符串。(继承自 Object)
UpgradeToWriterLock(Int32)
使用一个 Int32 超时值将读线程锁升级为写线程锁。
UpgradeToWriterLock(TimeSpan)
使用一个 TimeSpan 超时值将读线程锁升级为写线程锁。

代码示例

线程wt1和wt2是在WriteInts()方法中获取写程序锁的写程序线程,线程rt1和rt2是在ReadInts()方法中获取读程序锁的读程序线程。在WriteInts()方法中,实例变量x和y分别变为新值a和b。当线程wt1或wt2通过调用AcqireWriteLock()获取写程序锁时,其他线程(包括读程序线程rt1和rt2)就不能访问对象,直到线程wt1和wt2通过调用ReleaseWriterLock()释放了写程序锁。在ReadInts()方法中,线程rt1和rt2通ReleaseWriterLock()释放了写程序锁。在ReadInts()方法中,线程rt1和rt2通过调用 AcquireReadLock()方法获得读程序锁。在ReadInts()方法中,线程rt1和rt2可以同时访问实例变量x和y。写程序线程(wt1和wt2)都无法访问对象,直到读程序释放读程序锁。在获取读程序锁后,读程序线程才能同时访问对象

 using  System;
 using  System.Threading;
 using  System.Runtime.CompilerServices;
 public   class  ClassForMain
 {
    public class ReadWrite
    {
       private ReaderWriterLock rwl;
        private int x;
        private int y;
        public ReadWrite()
        {
            rwl = new ReaderWriterLock();
        }
        public void ReadInts(ref int a, ref int b)
        {
            rwl.AcquireReaderLock(Timeout.Infinite);
            try
            {
                a = this.x;
                b = this.y;
            }
            finally
            {
               rwl.ReleaseReaderLock();
            }
        }
        public void WriteInts(int a, int b)
        {
            rwl.AcquireWriterLock(Timeout.Infinite);
            this.x = a;
            this.y = b;
            try
            {
                Console.WriteLine("Begin write...");
                Console.WriteLine("x=" + this.x + "y=" + this.y + "ThreadID=" +
                Thread.CurrentThread.GetHashCode());
            }
            finally
            {
                rwl.ReleaseWriterLock();
                Console.WriteLine("End write!");
            }
        }
        public class RWApp
        {
            private ReadWrite rw = new ReadWrite();
            public static void Main(string[] args)
            {
                RWApp e = new RWApp();
                //Write Threads
                Thread wl1 = new Thread(new ThreadStart(e.Write));
                wl1.Start();
                Thread wl2 = new Thread(new ThreadStart(e.Write));
                wl2.Start();       
                //Reader Threads
                Thread rt1 = new Thread(new ThreadStart(e.Read));
                rt1.Start();
                Thread rt2 = new Thread(new ThreadStart(e.Read));
                rt2.Start();
                Thread rt3 = new Thread(new ThreadStart(e.Read));
                rt3.Start();
            }
            private void Write()
            {
                int a = 10;
                int b = 11;
                for (int i = 0; i < 5; i++)
                {
                    this.rw.WriteInts(a++, b++);
                    Thread.Sleep(1000);
                }
            }
            private void Read()
            {
                int a = 10;
                int b = 11;
                for (int i = 0; i < 5; i++)
                {
                    this.rw.ReadInts(ref a, ref b);
                    Console.WriteLine("For i=" + i + "||a=" + a + "||b=" + b +
                    "ThreadID=" + Thread.CurrentThread.GetHashCode());
                    Thread.Sleep(1000);
                }
            }
        }
    }
}

总结:

这篇文章比较简单,只是简单的学习一下,等博主有时间了出一篇详细的保姆级文章,对它有更多的认识,在有需求的时候最起码有路子,虽然很简单,但是也是可以学到东西的,我们学习了新的知识,对我们的知识储备及技术又有新的一点点的进步,C#的技术就是先简单再难嘛,积少成多之后才会成长才会进步,我们要不断的学习不断的探索,才能有学习的动力,才会有学习的欲望,创作不易,点赞评论收藏关注,嘿嘿,不喜勿喷!!!!

1235468900

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

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

相关文章

并发(9)

目录 50.AQS的核心思想是什么&#xff1f; 51.AQS有哪些核心方法&#xff1f; 52.AQS定义什么样的资源获取方式&#xff1f; 53.AQS底层使用了什么样的设计模式&#xff1f; 54.什么是可重入&#xff0c;什么是可重入锁&#xff1f;他用来解决什么问题&#xff1f; 55.Ree…

wireshark抓包分析HTTP协议,HTTP协议执行流程,

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 使用WireShark工具抓取「HTTP协议」的数据包&#…

超自动化助力企业财务转型升级

在快节奏的财务规划与分析环境中&#xff0c;传统的预算方法虽长期以来一直是企业制定有效决策的支柱&#xff0c;但已不足以驾驭当今复杂的商业环境。不断的经济变化、市场的不确定性以及利益相关者的需求增加促使企业寻求更敏捷的解决方案。如今&#xff0c;部分企业开始尝试…

关键字、标志符、变量、基本数据类型

1、关键字 1.1、定义 定义&#xff1a;被JAVA语言赋予了特殊含义&#xff0c;用作专门用途的字符串&#xff08;或单词&#xff09; 特点&#xff1a;全部关键字都是小写字母 上源码&#xff1a; 代码中定义类的关键字class&#xff0c;定义一个订单控制器类 ​​​​​​​…

try catch 应该在 for 循环里面还是外面

正文 首先 &#xff0c; 话说在前头&#xff0c; 没有什么 在里面 好 和在外面好 或者 不好的 一说。 本篇文章内容&#xff1a; 使用场景 性能分析 个人看法 1. 使用场景 为什么要把 使用场景 摆在第一个 &#xff1f; 因为本身try catch 放在 for循环 外面 和里面 …

7N65-ASEMI高压NPN型MOS管7N65

编辑&#xff1a;ll 7N65-ASEMI高压NPN型MOS管7N65 型号&#xff1a;7N65 品牌&#xff1a;ASEMI 连续漏极电流(Id)&#xff1a;4A 漏源电压(Vdss)&#xff1a;650V 栅极阈值电压&#xff1a;30V 单脉冲雪崩能量&#xff1a;150mJ 集电极电流&#xff08;脉冲&#xff…

【分布式微服务专题】SpringSecurity快速入门

目录 前言阅读对象阅读导航前置知识笔记正文一、Spring Security介绍1.1 什么是Spring Security1.2 它是干什么的1.3 Spring Security和Shiro比较 二、快速开始2.1 用户认证2.1.1 设置用户名2.1.1.1 基于application.yml配置文件2.1.1.2 基于Java Config配置方式 2.1.2 设置加密…

初识Linux shell

Linux初探 Linux系统可以划分为4个部分&#xff1a; Linux内核&#xff1a;Linux系统的核心&#xff0c;控制着系统的所有硬件和软件&#xff0c;在必要时分配硬件&#xff0c;并根据需要执行软件。 内核主要功能&#xff1a; 系统内存管理&#xff1a;内核通过硬件上称为交换…

Proxifier下载安装

一、下载地址 官网&#xff1a; https://www.proxifier.com/ 下载链接 https://www.proxifier.com/distr/ProxifierSetup.exe 因为这个跳转直接下载的&#xff0c;我放沙箱里试了一下 二、安装 安装就是同意协议&#xff0c;选择安装位置&#xff0c;因为是正版&#xff0c;他…

U-ViT【All are Worth Words: A ViT Backbone for Diffusion Models】

Motivation Diffusion中常用的Backbone是UNet&#xff0c;使用 resnet 和 transformer 交替进行的&#xff0c;这样内存memory存储 其实也是不断shuffle变化的&#xff0c;resnet 以 feature 看 memory&#xff0c;而 transformer 以 token 看memory。如果可以统一memory的计算…

Simpy简介:python仿真模拟库-02/5

一、说明 关于python下的仿真库&#xff0c;本篇为第二部分&#xff0c;是更进一步的物理模型讲解&#xff0c;由于这部分内容强依赖于第一部分的符号介绍&#xff0c;因此&#xff0c;有以下建议&#xff1a; 此文为第二部分&#xff0c;若看第一部分。建议查看本系列的第一部…

盲盒小程序搭建,功能优势分析

盲盒作为一种潮玩商品&#xff0c;吸引了大量的年轻人&#xff0c;受众群体非常高&#xff0c;在市场上的发展快速。盲盒拥有独特的优势&#xff0c;给消费者提供了新奇的购物体验&#xff0c;能够让人们在购物中体验到盲盒的不确定性所带来的惊喜感和快乐。 盲盒小程序的出现…

Echarts——使用graphic组件在一个option内同时设置两个饼图的背景图

使用echarts的graphic原生图形元素组件&#xff0c;为两个饼图设置对应背景。 <template><div id"app"><div class"charts" ref"charts"></div></div> </template><script> import * as echarts from…

计算机毕业设计 | SpringBoot+vue农产品商城 买菜购物网站(附源码)

1&#xff0c;绪论 1.1 项目背景 随着社会发展&#xff0c;网上购物已经成为我们日常生活的一部分。但是&#xff0c;至今为止大部分电商平台都是从人们日常生活出发&#xff0c;出售都是一些日常用品比如&#xff1a;食物、服装等等&#xff0c;并未发现一个专注于菜品的电商…

GEC6818传感器模块(烟雾+GY39+RFID)——使用文字取模的方式实现数据显示

GEC6818传感器模块(烟雾GY39RFID)——使用文字取模的方式实现数据显示 完整的工程大家可以在我的gitee上进行下载 下载地址&#xff1a;GEC6818智能语音家居系统 文章目录 GEC6818传感器模块(烟雾GY39RFID)——使用文字取模的方式实现数据显示一、 文字取模实现数据显示1. disp…

NPS 内网穿透安装

NPS 内网穿透安装 NPS分为服务端和客户端&#xff0c;对应的不同操作系统软件可以在GitHub RELEASES自行选择下载。 服务端搭建 由于个人非企业级使用&#xff0c;为了方便直接使用docker安装 1.docker运行 (注意需要提前下载conf文件&#xff0c;或者将镜像中文件copy出来…

多线程模板应用实现(实践学习笔记)

出处&#xff1a;B站码出名企路 个人笔记&#xff1a;因为是跟着b站的教学视频以及文档初步学习&#xff0c;可能存在诸多的理解有误&#xff0c;对大家仅供借鉴&#xff0c;参考&#xff0c;然后是B站up阳哥的视频&#xff0c;我是跟着他学。大家有兴趣的可以到b站搜索。加油…

C/C++ 联合体

目录 联合体概述 联合体的内存分配 联合体大小计算 联合体概述 联合与结构非常的相似&#xff0c;主要区别就在于联合这两个字。 联合的特征&#xff1a;联合体所包含的成员变量使用的是同一块空间。 联合体定义 //联合类型的声明 union Un {char c;int i; }; //联合变量…

isaacgym(legged_gym)学习 (二)—— 设置环境地形

isaacgym(legged_gym)学习 &#xff08;二&#xff09;—— 设置环境地形 文章目录 isaacgym(legged_gym)学习 &#xff08;二&#xff09;—— 设置环境地形前言一、了解isaacgym中地形如何构成的二、自定义修改1.代码2.查看script/play.py 总结 前言 如何设置isaacgym中的环…

【操作系统篇】正在持续写入的日志如何清理?

正在持续写入的日志如何清理? ✔️典型解析✔️ 推荐的日志管理工具✔️如何设置日志轮转工具✔️如何选择适合我的Logrote-NG日志轮转工具✔️如何测试Logrote-NG工具的稳定性✔️分析一个简单的ELK报警✔️这个报警的作用是什么✔️报警机制的优缺点✔️如何减少报警机制的误…