C# 说说lock

2023-11-06

一、MSDN的定义

lock 语句获取给定对象的互斥 lock,执行语句块,然后释放 lock。 持有 lock 时,持有 lock 的线程可以再次获取并释放 lock。 阻止任何其他线程获取 lock 并等待释放 lock。lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

lock 语句具有以下格式

lock (x)
{
    // Your code...
}

 其中 x引用类型的表达式。 它完全等同于

object __lockObj = x;
bool __lockWasTaken = false;
try
{
    System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
    // Your code...
}
finally
{
    if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}

 

二、lock原理


lock 关键字在块的开始处调用Monitor.Enter,而在块的结尾处调用Monitor.Exit。通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
如果实例可以被公共访问,将出现 lock (this) 问题。

如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。

锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。 这意味着整个程序中任何给定字符串都只有一个实例,进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。在 lock 语句的正文不能使用 等待 (await)关键字。

为什么锁的对象是私有的呢?还是以厕所为例子吧,私有就好比,这把锁只有你能访问到,而且最好这把锁不会因为外力而有所改变,别人访问不到,这样才能保证你进去了,别人就进不去了,如果是公有的,就好比你蹲位小单间的锁不是安装在里面而是安装在外边的,别人想不想进就不是你所能控制的了,这样也不安全。

三、使用lock实现单例模式

class SingletonClass
    {
        private static SingletonClass _instance = null;
        private static readonly object syncRoot = new object();   

        private SingletonClass()
        { 
        }

        public static SingletonClass GetInstance()
        {
            if (_instance == null)
            {
                lock (syncRoot)
                {
                    if (_instance == null)
                    {
                        _instance = new SingletonClass();
                    }
                }
            }
            return _instance;
        }
    }

在上述代码中出现“If - Lock - If”结构模式,即双重检查锁定的双重判断机制:

if (_instance == null)   //第一重判断,先判断实例是否存在,不存在再加锁处理
            {
                lock (syncRoot)   //加锁,在某一时刻只允许一个线程访问
                {
                    if (_instance == null)   //第二重判断: 第一个线程进入Lock中执行创建代码,第二个线程处于排队等待状态,当第二个线程进入Lock后并不知道实例已创建,将会继续创建新的实例
                    {
                        _instance = new SingletonClass();
                    }
                }
            }

下面几点需要注意的地方

1、lock的是引用类型的对象,string类型除外。

2、lock推荐的做法是使用静态的、只读的、私有的对象。

3、保证lock的对象在外部无法修改才有意义,如果lock的对象在外部改变了,对其他线程就会畅通无阻,失去了lock的意义。

 

参考:

https://www.cnblogs.com/goldendragon/p/9913600.html

https://www.cnblogs.com/youmingkuang/p/9987672.html

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/lock-statement?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(lock_CSharpKeyword)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%3Dv4.5)%3Bk(DevLang-csharp)%26rd%3Dtrue

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 说说lock 的相关文章

随机推荐

  • Javascript中的every()与some()的区别和应用

    every 定义和用法 every 方法用于检测数组所有元素是否都符合指定条件 通过函数提供 every 方法使用指定函数检测数组中的所有元素 如果数组中检测到有一个元素不满足 则整个表达式返回 false 且剩余的元素不会再进行检测 如果
  • 遗传的效应,美貌与智慧奇妙的遗传

    身高是母亲的遗传大 在营养状况下的前提下 父母的遗传是决定孩子身高的主要因素 其中妈妈的身高尤其关键 妈妈长得高 孩子也大多长得比较高 智力是母亲的遗传大 智力有一定的遗传性 同时受到环境 营养 教育等后天因素的影响 据科学家评估 遗传对智
  • 南大通用&河北工业大学人工智能与数据科学学院党支部共建暨研究生培养基地合作签约仪式顺利举办

    2022年2月18日下午 天津南大通用数据技术股份有限公司 河北工业大学人工智能与数据科学学院党支部共建签约仪式暨研究生培养基地签约仪式在普天创新产业园23层会议室举行 南大通用董事长丁明峰 高级副总裁赵伟 总工办主任杨伟伟 人力资源部总监
  • python中有哪些去除重复项的操作

    Python中去除重复项的操作 常用的有以下几种方式 1 使用set 将列表转化为集合 再转化为列表 即可去重 list a 1 2 3 2 1 4 5 4 6 7 7 new list a list set list a print ne
  • JMeter----安装与介绍以及简单页面录制和移动端录制

    1 什么是JMeter 2 JMeter的安装 3 JMeter基本使用 4 JMeter运行原理 5 JMeter录制脚本 1 什么是JMeter JMeter简介 JMeter是Apache公司使用Java平台开发的一套测试工具 JMe
  • flowable实战(三):关于流程图编辑

    发现很多人讲到flowable 就是大概讲一下整合里面一些名词之类 实操偏少 或者用一个小demo演示一下 就完了 但是一涉及到具体的业务 你会发现涉及到工作流要有多麻烦 考虑很多情况进去会涉及到条件设置 逻辑判断甚至官方提供的那么多方法你
  • C++实现人机对战围棋(使用Leela Zero权重)-界面

    1 在 leela zero next 包中有一个 从人类游戏训练的 较弱的 网络的权重文件 https sjeng org zero best v1 txt zip 6残差块 128通道 2 并在 easyx吧 百度贴吧下了一个双人对战的
  • C语言-函数指针-快速排序算法

    概述 使用C语言 实现结构体多元素 排序算法 冒泡排序 这里使用示例 蓝牙信号强度排序解说 编码环境 Visual Studio 2022 1 code include
  • Python int()的有趣用法

    Python中的int 函数相信大家都不陌生 总的来说 就是int 函数用于将字符串或数字转换为整型 那么今天要说的有趣用法是什么呢 先看一行代码 并猜一下它有什么作用 int 1 200 2 初看这行代码想半天也没搞懂 于是help in
  • 2014年12月4日星期四(DEMO10-2地形生成函数)

    转眼间 2014年快过去了 数了数代码 封装后的代码也有17000行了 但是 还有很多工作量 继续进行最为敬畏的地形生成 这个DEMO的意思是说 加载256色位图 以位图颜色索引乘以一个缩放因子为高程 将每个单元格分割为三角形 并插入到物体
  • 西瓜书《机器学习》课后答案——chapter5_5.5

    网络结构 这里采用简单的单隐层神经网络 输入层有2个神经元 隐层有4个神经元 输出层有2个神经元 隐层采用sigmoid激活函数 输出层采用softmax激活函数 z1 W1x b1 boldsymbol z 1 W 1 boldsymbo
  • Flutter之自动更新(自带源码 包看包会)

    Flutter做的App怎么自动更新呢 首先要用到两个依赖一个叫update app 另外一个叫package info 还有一个叫Dio 一个是用来下载App的 一个是用来获取当前App的版本信息的 一个是用来网络链接的 flutter
  • axure能做剪切蒙版吗_Axure图片裁切功能

    平时做原型时经常会用到一张图片的某些部分 这时候我们一般都会借助于其他图片处理工具先处理好 再导入到原型中 其实Axure有简单的图片裁切功能 基本可以满足我们大部分的需求 下面介绍一下 使用axure7 1 图片裁割 通过该功能可以把图片
  • C++ 中 enable_shared_from_this 的使用总结

    背景 enable shared from this 是 C 11 定义在头文件 include 中的一个模板类 其作用是在类的内部安全的得到 this 指针的 shared ptr 版本 获取 this 的 shared ptr 版本 概
  • 文件的blob、base64、File的转化

    前言 blob base64 File的互转 base64 File function toFile ndata ndata为base64格式地址 let arr ndata split mime arr 0 match 1 bstr at
  • DALL-E-2 论文水记

    DALL E 2 论文水记 模型示意图 虚线上面是 CLIP 的训练流程 虚线下面是文字生成图像的流程 我们有一个 prior 模型和一个 decode 模型 先把 text embeding 输入 prior 模型 得到 image em
  • How to run Android apps in tablet mode on your phone

    转自 http www littlegreenrobot co uk tutorials how to run android apps in tablet mode on your phone How to run Android app
  • 2.6内核的通用的编译步骤

    2 6内核的通用的编译步骤 1 下载源码并解压 虽然我们可以将内核源码存放在任何自己找得到的地方 但通常还是会将内核源码下载到 usr src目录并解压 cd usr src wget ftp kernel org pub linux ke
  • Android——AVD无法启动解决方法

    起因 最近安装了Android Studio开始瞎捣鼓 安装的时候配置的是自带的Android Virtual Device AVD 然后想在虚拟机上跑以下demo 发现虚拟机怎么都启动不了 起初我以为是系统找不到我的虚拟机的位置导致 因为
  • C# 说说lock

    一 MSDN的定义 lock 语句获取给定对象的互斥 lock 执行语句块 然后释放 lock 持有 lock 时 持有 lock 的线程可以再次获取并释放 lock 阻止任何其他线程获取 lock 并等待释放 lock lock 关键字可