c#中Lock的秘密
2021/6/10 22:21:00
本文主要是介绍c#中Lock的秘密,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、概要
本文主要讲解在c#中lock关键字的用法以及需要注意的坑。帮助大家避免使用不当造成的bug。
作用: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。在多线程中,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。
缺点: 多线程中频繁使用lock会造成性能损耗。
二、详细内容
(1)使用
以下是lock在单例中使用的,大家可以看到在Instance中有两个if判断_instance是否为空。为什么?因为lock在执行的过程中会有性能损耗如果已经初始化过了之后就不要在走lock加锁了,多线程中只读单例 对象是不会造成‘脏读’数据的。那么最外层的if就完美避免了lock的缺点。
public class Demo1
{
private static readonly object _lockObj = new object();
private static Demo1 _instance;
public static Demo1 Instance
{
get
{
if (_instance == null)
{
lock (_lockObj)
{
if (_instance == null)
{
_instance = new Demo1();
}
}
}
return _instance;
}
}
private Demo1() { }
public List<string> GetData()
{
return new List<string>();
}
}
(2)注意事项及原理
2.1注意事项
当同步对共享资源的线程访问时,请锁定专用对象实例(例如,private readonly object balanceLock = new object();)或另一个不太可能被代码无关部分用作 lock 对象的实例。 避免对不同的共享资源使用相同的 lock 对象实例,因为这可能导致死锁或锁争用。 具体而言,避免将以下对象用作 lock 对象:
- this(调用方可能将其用作 lock)。
- Type 实例(可以通过 typeof 运算符或反射获取)。
- 字符串实例,包括字符串文本,(这些可能是暂存的)。
- 尽可能缩短持有锁的时间,以减少锁争用。
- 在 lock 语句的正文中不能使用 await 运算符。
2.2原理(以下内容比较浅显,太深究内容一篇文章写不完)
Q1:大家会注意到,为什么要在lock的圆括号里放一个引用类型object?为什么不可以放一个值类型例如int?
A1:因为如果使用了值类型例如int作为lock锁定的对象,lock圆括号中的入参是object类型当传入了值类型会对传入的对象类型进行转换,那么在IL层面会对值类型进行一次装箱(box)操作。那么这种情况下就不具备lock锁定需要用到专用对象的稳定性了。
IL_0002:ldloc.0
IL_0003:box [mscorlib]System.Int32
A2:第二个原因这个就需要追溯到“值类型”和“引用类型”的基类,大家都知道引用类型的基类是object、值类型的基类是ValueType这两种基类本质的区别如下:
- 值类型:构造中不包含同步块索引。
- 引用类型:构造中包含同步块索引。
除了c#语法不支持以外它不适宜作为lock圆括号中的锁定对象的原因就是没有同步块索引。
这篇关于c#中Lock的秘密的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具
- 2024-01-24.NET集成IdGenerator生成分布式全局唯一ID
- 2024-01-23用CI/CD工具Vela部署Elasticsearch + C# 如何使用
- 2024-01-23.NET开源的简单、快速、强大的前后端分离后台权限管理系统