博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 说说lock
阅读量:4092 次
发布时间:2019-05-25

本文共 2200 字,大约阅读时间需要 7 分钟。

一、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的意义。

 

参考:

 

转载地址:http://lkiii.baihongyu.com/

你可能感兴趣的文章
接口隔离原则
查看>>
依赖倒转(置)原则
查看>>
真正解决方案:java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
查看>>
bean的作用范围与bean的生命周期
查看>>
BeanFactory与FactoryBean的区别
查看>>
修改Ant Design Vue树形表格的展开图标样式
查看>>
Spring中@interface的作用
查看>>
Filebeat配置实现不同路径下的log文件作为数据源
查看>>
Logstash过滤器插件filter
查看>>
Logstash输入源的三种配置方式
查看>>
CSS中hover的使用细节
查看>>
Ant Design Vue中change等方法如何传递自定义参数
查看>>
Springboot的logback-spring.xml配置
查看>>
URI中特殊字符的处理
查看>>
Linux中使用ps命令查看进程的介绍
查看>>
RBAC:基于角色的权限访问控制
查看>>
Linux中使用nohup实现后台运行程序
查看>>
nc命令介绍
查看>>
netstat命令介绍
查看>>
Java知识:变量在内部类中被使用的话必须在内部类外部声明为final
查看>>