C#中的lock关键字
前几天与同事激烈讨论了一下,有一点收获,记录起来。
首先给出MSDN的定义:
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
先来看看执行过程,代码示例如下:

假设线程A先执行,线程B稍微慢一点。线程A执行到lock语句,判断obj是否已申请了互斥锁,
判断依据是逐个与已存在的锁进行object.ReferenceEquals比较(此处未加证实),如果不存
在,则申请一个新的互斥锁,这时线程A进入lock里面了。
这时假设线程B启动了,而线程A还未执行完lock里面的代码。线程B执行到lock语句,检查到obj
已经申请了互斥锁,于是等待;直到线程A执行完毕,释放互斥锁,线程B才能申请新的互斥锁并执行
lock里面的代码。
接下来说一些该lock什么对象。
为什么不能lock值类型,比如lock(1)呢?lock本质上Monitor.Enter,Monitor.Enter会使值类型装箱,
每次lock的是装箱后的对象。lock其实是类似编译器的语法糖,因此编译器直接限制住不能lock值类型。
退一万步说,就算能编译器允许你lock(1),但是object.ReferenceEquals(1,1)始终返回false(因为
每次装箱后都是不同对象),也就是说每次都会判断成未申请互斥锁,这样在同一时间,别的线程照样能
够访问里面的代码,达不到同步的效果。同理lock((object)1)也不行。
那么lock("xxx")字符串呢?MSDN上的原话是:
锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。 这意味着整个程序中任何给定字符串
都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用
程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。
通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,
则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线
程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。而且lock(this)
只对当前对象有效,如果多个对象之间就达不到同步的效果。
lock(typeof(Class))与锁定字符串一样,范围太广了。
某些系统类提供专门用于锁定的成员。例如,Array 类型提供 SyncRoot。许多集合类型也提供 SyncRoot。
而自定义类推荐用私有的只读静态对象,比如:
private static readonly object obj = new object();
为什么要设置成只读的呢?这时因为如果在lock代码段中改变obj的值,其它线程就畅通无阻了,因为互斥锁的
对象变了,object.ReferenceEquals必然返回false。
C#中的lock关键字的更多相关文章
- C#中的lock关键字有何作用
作为C#的程序员来说,在遇到线程同步的需求时最常用的就是lock关键字.但如何正确并有效地使用lock,却是能否高效地达到同步要求的关键.正因为如此,程序员需要完全理解lock究竟为程序做了什么. 所 ...
- C#中的lock关键字;就是lock住一个大家都共同访问的(静态static的)东东就行了
public class ChatService : IChat //继承IChat接口或者说IChat的实现类 { //定义一个静态对象用于线程部份代码块的锁定,用于lock操作 private s ...
- C#中的lock关键字(初识)
http://kb.cnblogs.com/page/88513/ 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互 ...
- (转载)C#中的lock关键字
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. 先来看看执行过程,代码示例如下: 假设线程A先执行,线程B稍微慢一点.线程A执 ...
- C#中Monitor类、Lock关键字和Mutex类
线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程.多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率.多线程的应用程序域是相当不稳定的,因为多个线程 ...
- c#多线程中Lock()关键字的用法小结
本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...
- C#中Monitor对象与Lock关键字的区别分析
这篇文章主要介绍了C#中Monitor对象与Lock关键字的区别,需要的朋友可以参考下 Monitor对象 1.Monitor.Enter(object)方法是获取 锁,Monitor.Exit(ob ...
- 转:C#中Monitor对象与Lock关键字的区别分析
Monitor对象1.Monitor.Enter(object)方法是获取 锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...
- C#中Lock关键字的使用
C# 中的 Lock 语句通过隐式使用 Monitor 来提供同步功能.lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit. 通常,应避免锁定 public 类型,否则实例将超 ...
随机推荐
- Robot Framework 环境搭建
一.下载软件 1.安装Python 到官网,下载Python 2.7.9:https://www.python.org/downloads/,最好选择32位版本的(64位系统也支付32位版本),然后安 ...
- POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问
今天学了很多关于树状数组的技巧.一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用 ...
- Javascript的9张思维导图学习
思维导图小tips:思维导图又叫心智图,是表达发射性思维的有效的图形思维工具 ,它简单却又极其有效,是一种革命性的思维工具.思维导图运用图文并重的技巧,把各级主题的关系用相互隶属与相关的层级图表现出来 ...
- Ubuntu环境下手动配置HBase0.94.25
/×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...
- String与StringBuilder
package com.wangzhu.string; /** * String类是final类,也就是说String类不能被继承,并且其成员方法都默认为final方法.<br/> * * ...
- cojs 奈特 题解报告
才知道knight念奈特,而不念科耐特 这个题显然是一个数据结构题目,我搬运的CF上的题 CF的题解好长超长哒,而且可以在线,但是并不能看懂 于是自己想了一个一种做法A掉了,唯一的缺陷就是做法有些繁琐 ...
- 李洪强iOS开发之OC语言description方法和sel
OC语言description方法和sel 一.description方法 Description方法包括类方法和对象方法.(NSObject类所包含) (一)基本知识 -description(对象 ...
- 【memcache缓存专题(1)】memcache的介绍与应用场景
简介 Memcached是一个高性能的分布式的内存对象缓存系统,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各 ...
- QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 分类: QT2009-10-28 13:33 17695人阅读 评论(13) 收藏 举报 qtapplicationwindowse ...
- Photoshop CS4序列号过期的问题
1)在网络上搜寻一些PS CS4序列号: 如1330-1221-6824-4838-0308-6823,1330-1283-7461-4574-7002-2504,1330-1795-2880-537 ...