c# lock详细介绍与实现

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。

先来看看执行过程,代码示例如下:

lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁。
lock-statement:(lock 语句:)
lock   (   expression   )   embedded-statement(lock   (   表达式   )   嵌入语句)
lock 语句的表达式必须表示一个引用类型的值。永远不会为 lock 语句中的表达式执行隐式装箱转换(第 6.1.5 节),因此,如果该表达式表示的是一个值类型的值,则会导致一个编译时错误。
下列形式的 lock 语句
lock (x) ...
(其中 x 是一个引用类型的表达式)完全等效于

system.threading.monitor.enter(x);
try {
   ...
}
finally {
   system.threading.monitor.exit(x);
}

不同的只是:实际执行中 x 只计算一次。
当一个互斥锁已被占用时,在同一线程中执行的代码仍可以获取和释放该锁。但是,在其他线程中执行的代码在该锁被释放前是无法获得它的。
一个类的 system.type 对象可以方便地用来当作关于该类的静态方法的互斥锁。例如:

class cache
{
   public static void add(object x) {
      lock (typeof(cache)) {
         ...
      }
   }
   public static void remove(object x) {
      lock (typeof(cache)) {
         ...
      }
   }
}

假设线程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。

 

时间: 2024-10-16 03:32:10

c# lock详细介绍与实现的相关文章

分享十款最出色的PHP安全开发库中文详细介绍

  1. PHP入侵检测系统 开发库中文详细介绍-芭提雅6996详细介绍"> PHP IDS(即PHP-入侵检测系统)是一套易于使用.结构良好.速度出色且专门面向PHP类Web应用程序的先进安全层.这套入侵检测系统既不提供任何缓和及杀毒机制,也不会对恶意输入内容进行过滤,其作用单纯为识别出攻击者们针对站点进行的恶意活动.并以大家需要的方式作出及时提醒.凭借着一整套经过实践检验及相当严格的过滤规则,该检测系统会针对任何攻击活动给出一个影响评级数值,从而帮助用户更轻松地了解应如何应对当前出现的

Java 高并发五:JDK并发包1详细介绍_java

在[高并发Java 二] 多线程基础中,我们已经初步提到了基本的线程同步操作.这次要提到的是在并发包中的同步控制工具. 1. 各种同步控制工具的使用 1.1 ReentrantLock ReentrantLock感觉上是synchronized的增强版,synchronized的特点是使用简单,一切交给JVM去处理,但是功能上是比较薄弱的.在JDK1.5之前,ReentrantLock的性能要好于synchronized,由于对JVM进行了优化,现在的JDK版本中,两者性能是不相上下的.如果是简

small标签详细介绍

html教程,small标签详细介绍. 类似于<em></em>之类的短语元素,既可以改进文档结构,同时也保留了预期的视觉样式.但<small></small>在平时应用中不是很常见,第一眼的影响是淘宝UED是不是在这个小问题上疏忽了? 关于<small></small>,网上搜索下来的结果也很零碎,有的说不建议使用,也有的在废弃标签里没有提到它的名字.好在<精通HTML 语义.标准和样式>一书中对此作了详细的解释. &l

微博1分钱变5000元活动网址内容规则详细介绍

  新浪微博开启了"1分钱变5000元现金"活动,用于推广微博支付.在活动期间内(4月25日-5月5日),只要用户通过微博支付成功支付1分钱,变会100%获得现金礼包,金额从1元到5000元不等.下面小编为大家详细介绍微博1分钱变5000元活动详细内容. 活动时间:2014年4月25日-5月5日 参与方式:使用微博支付成功支付一分钱,即可100%获得微博支付的现金奖励,金额最低1元,最高5000元 无论是否绑定过支付宝都可以参与该活动,未绑定的需要绑定.获得的奖金将在7个工作日内打到对

PHP Streams(流)详细介绍及使用

  这篇文章主要介绍了PHP Streams(流)详细介绍及使用,PHP Streams是内置核心操作,可能一般的开发者很少用,它用于统一文件.网络.数据压缩等类文件操作方式,并为这些类文件操作提供一组通用的函数接口,需要的朋友可以参考下 PHP Streams是内置核心操作,可能一般的开发者很少用,它用于统一文件.网络.数据压缩等类文件操作方式,并为这些类文件操作提供一组通用的函数接口. 一个stream就是一个具有流式行为的资源对象,每个stream对象都有一个包装类.Stream 可以通过

详细介绍ASP.NETWeb相关服务

经过长时间学习ASP.NETWeb,于是和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西.学习ASP.NETWeb时,你可能会遇到相关问题,这里将介绍ASP.NETWeb问题的解决方法. 该结构分三个层次:表示层.业务层.数据层.数据层:代表物理数据库.业务层:负责数据层与表示层之间的数据传输.表示层:应用程序的客户端,它通过业务层来访问数据库. 表示层所操作的是驻留在内存中的本地数据,当需要更新数据库数据时,要通过业务层提供的更新方法实现.这样可以大大提高应用程序的性能,而且

十款最出色的PHP安全开发库中文详细介绍(1)

1. PHP入侵检测系统 开发库中文详细介绍(1)-webapp详细开发介绍"> PHP IDS(即PHP-入侵检测系统)是一套易于使用.结构良好.速度出色且专门面向PHP类Web应用程序的先进安全层.这套入侵检测系统既不提供任何缓和及杀毒机制,也不会对恶意输入内容进行过滤,其作用单纯为识别出攻击者们针对站点进行的恶意活动.并以大家需要的方式作出及时提醒.凭借着一整套经过实践检验及相当严格的过滤规则,该检测系统会针对任何攻击活动给出一个影响评级数值,从而帮助用户更轻松地了解应如何应对当前出

css教程:关于CSS不透明的详细介绍

  近年来,CSS不透明算得上是一种相当流行的技术,但在跨浏览器支持上,对于开发者来说,可以说是一件令人头疼的事情.目前还没有一个通用方法,以确保透明度设置可以在目前使用的所有浏览器上有效. 这篇汇总主要是提供一些CSS不透明的详细介绍,代码示例和解释,以实现这项有用的CSS技术在您的项目中兼容所有浏览器. 关于CSS 透明度,有一点需要注意的是,它虽然使用了很多年,但它一直以来都不是一个标准属性.它是一种非标准技术,应该是CSS3规范的一部分. 1. 旧的Opacity设置 以下代码是Fire

详细介绍CSS的三种selector

css|select CSS的三种selector 上一节开始我们讨论 CSS (Cascading Style Sheet) 的基础. 告诉你有三种 Selector. 但只介绍了其中的 HTML selector. 这一节我们把三种都详细介绍给你HTML selector.class selector.ID selector: HTML selector HTML selector 就是 HTML 的 tags, 比如 P, DIV, TD 等. 如你用 CSS 定义了它们, 在整页中, 这