本文共 2200 字,大约阅读时间需要 7 分钟。
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);}
如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。 这意味着整个程序中任何给定字符串都只有一个实例,进程中使用同一字符串的任何其他代码都将共享同一个锁,所以出现 lock("myLock") 问题。最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。在 lock 语句的正文不能使用 等待 (await)关键字。
为什么锁的对象是私有的呢?还是以厕所为例子吧,私有就好比,这把锁只有你能访问到,而且最好这把锁不会因为外力而有所改变,别人访问不到,这样才能保证你进去了,别人就进不去了,如果是公有的,就好比你蹲位小单间的锁不是安装在里面而是安装在外边的,别人想不想进就不是你所能控制的了,这样也不安全。
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/