C# Monitor锁

一、Lock和Monitor的关系

二、Monitor多于Lock的功能

三、Monitor常用属性和方法


一、Lock和Monitor的关系

Lock在IL代码中会被翻译成Monitor。lock(obj){} 等同于 Monitor.Enter(obj)和Monitor.Exit(obj)

lock 是语法糖,是通过 Monitor 来实现的。

lock能做的Monitor肯定能做,Monitor能做的lock不一定能做

二、Monitor多于Lock的功能

1、Monitor.TryEnter(obj,timespan)----timeout之后,就不执行这段代码了。lock会一直死等。

2、还有Monitor.Wait()和Monitor.Pulse()。在lock代码里面如果调用了Monitor.Wait(),会放弃对资源的所有权,让别的线程lock进来。然后别的线程代码里Pulse一下(让原线程进入到等待队列),然后在Wait一下释放资源,这样原线程的就可以继续执行了(代码还堵塞在wait那句话呢)。

也就是说,必须两个或多个线程共同调用Wait和Pulse,把资源的所有权抛来抛去,才不会死锁。

和AutoEvent相似是处理同步关系的,但是AutoEvent是跨进程的,而Monitor是针对线程的。

三、Monitor常用属性和方法

**Enter(Object)**在指定对象上获取排他锁。

**  Exit(Object)**释放指定对象上的排他锁。

IsEntered确定当前线程是否保留指定对象锁。

** Pulse**通知等待队列中的线程锁定对象状态的更改。

PulseAll通知所有的等待线程对象状态的更改。

**TryEnter(Object)**试图获取指定对象的排他锁。

**TryEnter(Object, Boolean)**尝试获取指定对象上的排他锁,并自动设置一个值,指示是否得到了该锁。

**Wait(Object)**释放对象上的锁并阻止当前线程,直到它重新获取该锁。

常用的方法有两个,Monitor.Enter(object) 方法是获取锁,**Monitor.Exit(object)**方法是释放锁,这就是Monitor最常用的两个方法,在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit())。

TryEnter(Object)TryEnter() 方法在尝试获取一个对象上的显式锁方面和 Enter() 方法类似。然而,它不像Enter()方法那样会阻塞执行。如果线程成功进入关键区域那么TryEnter()方法会返回true. 和试图获取指定对象的排他锁

我们可以通过Monitor.TryEnter(monster, 1000),该方法也能够避免死锁的发生,Monitor.TryEnter(Object,Int32)。 设置1S的超时时间,如果在1S之内没有获得同步锁,则返回false,也就是说,在1秒中后,lockObj还未被解锁,TryEntry方法就会返回false,如果在1秒之内,lockObj被解锁,TryEntry返回true。我们可以使用这种方法来避免死锁

注:Wait 和 Pulse 方法必须写在 Monitor.Enter 和Moniter.Exit 之间

相关推荐
测试_AI_一辰1 小时前
项目实践笔记13:多用户事实碎片 Agent 的接口测试与约束设计
开发语言·人工智能·ai编程
twj_one1 小时前
java中23种设计模式
java·开发语言·设计模式
梵刹古音1 小时前
【C语言】 跳转语句
c语言·开发语言·算法
阿猿收手吧!1 小时前
【C++】C++模板特化:精准定制泛型逻辑
开发语言·c++·算法
ghie90902 小时前
MATLAB中编写不平衡磁拉力方程
开发语言·matlab
weixin_452159552 小时前
C++与Java性能对比
开发语言·c++·算法
会叫的恐龙2 小时前
C++ 核心知识点汇总(第一日)(输入输出与变量、类型转换)
开发语言·c++
2301_765703142 小时前
C++中的工厂模式实战
开发语言·c++·算法
电商API&Tina2 小时前
电商数据采集 API 接口 全维度解析(技术 + 商业 + 合规)
java·大数据·开发语言·数据库·人工智能·json
小白学大数据2 小时前
实测数据:多进程、多线程、异步协程爬虫速度对比
开发语言·爬虫·python·php