一篇文章带你轻松了解C# Lock关键字
作者:ZaraNet 发布时间:2023-08-15 20:48:32
相信绝大多数.NET玩家和我一样,常常使用Timer这个对象,而在WPF中使用DispatcherTimer的人也是很多,DispatcherTimer是在UI线程跑的。我们的程序中大多数都会充斥很多Timer,可以理解它是一个线程,它继承自 System.Windows.Threading 。
程序中也许会有一些静态变量或是单例模式的对象来让不同的页面进行交互,但也就是这样让每个线程之间打架提供了基础。因为资源是单独的,就像是脚踩两只船的人,必定会翻车。例如一个List集合,你在一个线程中对它进行了操作,在同步瞬间的另线程中,如果不对它谨慎处理,就会造成 “集合已修改;可能无法执行枚举操作”。当然我们说的不是关于集合的相关问题,而是关于资源分配的,当然在资源抢夺上,是在耗时的线程中才会出现的,例如下面的这张图。
这种耗时的操作,并且在同步线程中,没有对线程进行封装,很容易造成资源抢夺问题,假如Object是个集合,我在中间把它改了,下一秒的其它线程对它进行脏读了,就会产生错误,我们可以通过Lock关键字。
首先在Microsoft文档中对Lock的说明是,lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
不过我们需要注意的是Lock本质上Monitor.Enter,Monitor.Enter会使值类型装箱,每次Lock的是装箱后的对象。Lock其实是类似编译器的语法糖,因此编译器直接限制住不能lock值类型,为啥呢,你仔细想想,每次装箱后都是不同的对象,我怎么判断? object.ReferenceEquals 每次都是false...还有就是千万不要Lock 字符串,简单来说Lock字符串之后,只要是你以后有字符串匹配和你Lock里的内容有一样的,那个该字符串也会被锁定,相当于死锁了。
Lock和Monitor的区别不是很大,具体看以下代码。
private static object obj = new object();
public void LockSomething()
{
lock (obj)
{
dosomething();
}
}
public void MonitorSomeThing()
{
Monitor.Enter(obj);
dosomething();
Monitor.Exit(obj);
}
public void dosomething()
{
//做具体的事情
}
lock和Monitor是.NET用一个特殊结构实现的,Monitor对象是完全托管的、完全可移植的,并且在操作系统资源要求方面可能更为有效,同步速度较快,但不能跨进程同步。主要作用是锁定临界区,使临界区代码只能被获得锁的线程执行。Monitor.Wait和Monitor.Pulse用于线程同步,类似信号操作,个人感觉使用比较复杂,容易造成死锁。
lock就是封装了Monitor.Enter和Monitor.Exit方法其实非常不难理解,只要确定Lock在啥时候用,该怎么用就可以了,总结一句话。经常会应用于防止多线程操作导致公用变量值出现不确定的异常,用于确保操作的安全性。
来源:https://www.cnblogs.com/ZaraNet/p/13083286.html
猜你喜欢
- 我们通过一个完整的实例来实现课程信息管理功能的操作,包括查询、修改、删除课程信息的操作。为了简化实例,添加课程信息的操作直接在 SQL Se
- Android仿360悬浮小球自定义view实现示例效果图如下:实现当前这种类似的效果 和360小球 悬浮桌面差不错类似。这种效果是如何实现
- 就像集成JDBC和其他ORM框架一样,Spring也集成了iBatis。1,配置iBatis客户模板iBatis的核心是com.ibatis
- windows应用程序(包括控制台)在运行时如果出现了未处理的异常会出项windows的异常提示框 &nb
- 本篇开始介绍Jetpack Compose 中的修饰符Modifier。修饰符可以用来执行以下操作:更改可组合项的大小、布局、行为和外观。添
- 正则: “.”和"\""."点儿,在正则表达式中表示任意一个字符。"\"在正则表
- 前言在Flutter实际开发中,大家可能会遇到flutter框架中提供的widget达不到我们想要的效果,这时就需要我们去自定义widget
- 先看一下Android悬浮按钮点击回到顶部的效果:FloatingActionButton是Design Support库中提供的一个控件,
- 本文实例为大家分享了android利用handler实现倒计时的具体代码,供大家参考,具体内容如下xml<?xml version=&
- 一直以来不是怎么清楚自旋锁,最近有点时间,好好的学习了一下;所谓的自旋锁在我的理解就是多个线程在尝试获取锁的时候,其中一个线程获取锁之后,其
- 本文描述了TCP协议,首先简单介绍了TCP完成了一些什么功能;介绍了TCP报文格式,以及典型报文的数据格式;接着从链路控制和数据传输两个方面
- 最近有人问我如何实现倒计时的按钮功能,例如发送验证码,我记得有个CountDownTimer,因为好久没用过了,自己就写了一个,代码如下 n
- Springboot 在普通类型注入Service或mapper最近遇到一个难题(大佬可能感觉这太简单了把),对于我这样的小白来说,确实有些
- 一、Java内存区域方法区(公有):用户存储已被虚拟机加载的类信息,常量,静态常量,即时编译器编译后的代码等数据。异常状态 OutOfMem
- 就是仿照现在扫一扫的形式,周围是半透明的遮挡,然后中间是全透明的,拍摄后只截取框内的内容查了很多博客,实现起来真的太复杂了,本人比较怕麻烦所
- 前言在有些业务场景中,系统对于响应时间有一定的要求,而一个方法里面同步执行的业务逻辑太多势必会影响响应速度,带来不好的用户体验。比如登录时记
- * 是许多框架底层实现的基础,比如Spirng的AOP等,其实弄清楚了 * 的实现原理,它就没那么神奇了,下面就来通过案例和分析JDK
- import java.util.LinkedList;public class OJ { public OJ() {
- 本例为模仿微信聊天界面UI设计,文字发送以及语言录制UI。1先看效果图: 第一:chat.xml设计 &l
- 一、JPype简述1.JPype是什么?JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python