当前位置: 首页 > news >正文

C#多线程同步利器:Monitor全解析

C#多线程同步利器:Monitor全解析

  • 一、Monitor是什么
  • 二、Monitor 用在什么场景?这两类场景必用
  • 三、实战Demo:3个示例掌握Monitor核心用法
    • 示例1:基础用法——Enter/Exit 的 “标准姿势”
    • 示例2:进阶用法——用TryEnter避免“无限等待”
    • 示例3:高级用法——生产者-消费者模型(Wait/Pulse实战)
  • 四、Monitor 核心方法速查表(建议收藏)
  • 五、避坑指南
  • 总结:Monitor的“核心价值”

C#多线程同步利器:Monitor全解析

多线程编程中,共享资源的并发访问常引发数据混乱。而C#的 Monitor 就像一把精准的安全锁,能让多线程 “有序排队”,是保障数据一致性的基础工具,也是编写稳健多线程程序的必备知识

一、Monitor是什么

Monitor是C#提供的线程同步工具类,核心作用只有一个:保证同一时刻只有一个线程能访问“共享资源”。如果把共享资源比作 “单人间”,Monitor 就是房间的 “门锁”:

  • 线程要进房间(访问资源),必须先拿钥匙(获取 Monitor 的 “锁”)
  • 拿到钥匙的线程在房间里时(执行临界区代码),其他线程只能在门外排队(阻塞等待)
  • 线程离开房间后(完成操作),必须把钥匙还回来(释放锁),下一个排队的线程才能进去

这种“互斥访问”的机制,就是Monitor解决线程安全问题的核心逻辑。更重要的是,它还有Wait/Pulse这样的 “进阶技能”,能实现线程间的“协作”—— 让线程按需等待或唤醒,应对更复杂的同步场景

二、Monitor 用在什么场景?这两类场景必用

Monitor的价值,在“多线程操作共享资源”和“线程间需配合”时最突出,这两类场景几乎是多线程开发的 “高频考点”:

  1. 共享资源的互斥访问,避免数据错乱
  • 多个线程要读写同一份数据(比如计数器、缓存、配置项)。若不做同步,极易出现“数据覆盖”或“结果错乱”
  • 用Monitor(或其语法糖lock)锁定“读-改-写”的过程,能确保同一时间只有一个线程操作,避免这类问题
  1. 线程间的有序协作,按需等待与唤醒
  • 当线程需要“互相配合”时,Wait/Pulse是关键
  • 最经典的就是 “生产者 - 消费者模型”:生产者生成数据后,要通知消费者来处理;消费者没数据时,需等待生产者的通知。实现“按需等待、即时响应”,避免线程空转浪费资源,效率大幅提升

三、实战Demo:3个示例掌握Monitor核心用法

示例1:基础用法——Enter/Exit 的 “标准姿势”

  • Monitor 最基础的用法是 “获取锁 - 执行临界区 - 释放锁”,对应 Enter 和 Exit 方法。注意必须 “成对出现”,且释放锁要放在 finally 里(防异常导致锁没释放)
//创建一个用于线程同步的共享对象
//readonly 确保该对象在初始化后不会被重新赋值,避免同步失效
private static readonly object _lockObj = new object();
static void MonitorEnterExitDemo()
{Monitor.Enter(_lockObj); // 获取锁,进入临界区,此时其他线程若尝试获取该锁,将被阻塞try{// 临界区代码}finally{// 离开临界区,释放锁:无论try里是否抛异常,都能确保锁被释放Monitor.Exit(_lockObj); }
}
  • 小提示:若只是简单的 “锁 - 执行 - 放”,更推荐使用lock语句——它本质是Monitor.Enter+try-finally+Monitor.Exit的语法糖,代码更简洁,且能避免手动释放锁的疏漏 一文读懂 C# 中的 lock:多线程编程的“安全锁”

示例2:进阶用法——用TryEnter避免“无限等待”

  • lockMonitor.Enter 有个问题:若拿不到锁,线程会一直阻塞
  • Monitor.TryEnter 更灵活:会“尝试”拿锁,拿不到就返回false,还能设置“超时时间”,适合不希望线程无限等待的场景
private static readonly object _lockObj = new object(); 
static void MonitorTryEnterExitDemo()
{bool lockTaken = false; // 标记是否成功拿到锁try<
http://www.dtcms.com/a/347388.html

相关文章:

  • 安卓10.0系统修改定制化____如何修改固件 去除开机后默认的屏幕锁定
  • AcWing 114. 【0x07】国王游戏
  • C代码学习笔记(一)
  • Windows打开命令窗口的几种方式
  • 使用 PSRP 通过 SSH 建立 WinRM 隧道
  • 注意力机制中为什么q与k^T相乘是注意力分数
  • 每日定投40刀BTC(22)20250802 - 20250823
  • 编程刷题-染色题DFS
  • 03_数据结构
  • 在 CentOS 7 上搭建 OpenTenBase 集群:从源码到生产环境的全流程指南
  • MSPM0G3507工程模板创建
  • 微信小程序自定义组件开发(上):从创建到数据通信详解(五)
  • 纠删码技术,更省钱的分布式系统的可靠性技术
  • 使用springboot开发-AI智能体平台管理系统,统一管理各个平台的智能体并让智能体和AI语音设备通信,做一个属于自己的小艾同学~
  • Dubbo vs Feign
  • 个人思考与发展
  • 探秘北斗卫星导航系统(BDS):架构、应用与未来蓝图,展现中国力量
  • 详细说一说JIT
  • Redis面试精讲 Day 28:Redis云原生部署与Kubernetes集成
  • Js逆向 拼夕夕anti_content
  • 深入解析Spring Boot自动配置原理:简化开发的魔法引擎
  • Java基础第2天总结
  • 青少年机器人技术(四级)等级考试试卷-实操题(2021年12月)
  • 互联网大厂Java面试实战:核心技术栈与场景化提问解析(含Spring Boot、微服务、测试框架等)
  • Java 遗传算法在中药药对挖掘中的深度应用与优化策略
  • 雨雾天气漏检率骤降80%!陌讯多模态车牌识别方案实战解析
  • Redis--day10--黑马点评--秒杀优化消息队列
  • 【JavaEE】多线程 -- JUC常见类和线程安全的集合类
  • 什么猫粮好?2025最新猫粮排名合集
  • 深度解析Bitmap、RoaringBitmap 的原理和区别