当前位置: 首页 > news >正文

C#多线程编程之:lock使用注意事项

1.避免锁定public类型对象。

  如果实例可以被公共访问,将出现lock(this)问题。

  如有一个类MyClass,该类有一个Method方法通过lock(this)来实现互斥:

复制代码
1 public class MyClass
2 {
3 public void Method()
4 {
5 lock(this)
6 {
7 ......
8 }
9 }
10 }
复制代码

  如果一个MyClass的实例在不同线程中执行Method方法,可以实现互斥。但如果多个MyClass的实例分别在不同的线程中执行Method方法,互斥将失效,因为此处的lock(this)仅对当前的实例对象进行了加锁。

2.禁止锁定类型

  lock(typeof(ClassName))锁定范围更为广泛,由于一个类的所有实例都只有一个类型对象(该对象是typeof的返回结果),锁定它,就锁定了该对象的所有实例。微软现在建议(原文请参考:http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/SDaskgui06032003.mspx?mfr=true)不要使用lock(typeof(ClassName))。以下的微软的原文描述:

  首先锁定类型对象是个很缓慢的过程,并且类中的其他线程、甚至在同一个应用程序域中运行的其他程序都可以访问该类型对象,因此,它们就有可能代替您锁定类型对象,完全阻止您的执行,从而导致你自己的代码的挂起。

  这里的基本问题是,您并未拥有该类型对象,并且您不知道还有谁可以访问它。总的来说,依靠锁定不是由您创建、并且您不知道还有谁可以访问的对象是一种很不好的做法。这样做很容易导致死锁。

3.禁止锁定字符串

  锁住一个字符串更为神奇,只要字符串内容相同,就能引起程序挂起。

  在.NET中,字符串会被暂时存放,如果两个变量的字符串内容相同的话,.NET会把暂存的字符串对象分配给该变量。所以如果有两个地方都在使用lock("my lock")的话,它们实际锁住的是同一个对象。

如何正确使用lock呢?

  微软给出的建议是:只锁定私有对象。

  示例代码: 

复制代码
1 public class MyClass
2 {
3 private static Object somePrivateStaticObject = new Object();
4
5 // methods of class go here--can lock somePrivateStaticObject
6 public void Method()
7 {
8 lock(somePrivateStaticObject)
9 {
10 ......
11 }
12 }
13 }
复制代码

锁定私有对象的好处:

  首先,类以外的任何代码都无法锁定MyClass.somePrivateStaticObject,因此避免了许多死锁的可能。由于死锁属于那种最难找到根源的问题,因此,避免发生死锁的可能是一件很好的事情。

  其次,应用程序中只有一份MyClass.somePrivateStaticObject的副本,并且系统上运行的其他每个应用程序也只有一个副本。因此,在同一个应用程序域中的应用程序之间没有相互影响。

转载于:https://www.cnblogs.com/soundcode/p/6571167.html

相关文章:

  • kmp模式串匹配
  • java 面向对象 — 多态
  • Java容器-引用分类与部分Map用法
  • 在Kotlin编写RecyclerView适配器(KAD 16)
  • web-app 与本地app的区别
  • JS 面向对象例题
  • Idea中的插件-列出Java Bean的所有set方法
  • JavaScript的数据类型与变量
  • Android 权限的实现
  • 看《神探夏洛克》经典台词
  • 挂载硬盘,并分区格式化
  • JavaScript中的对象
  • 用vs2015 编译 web app ionic
  • HTTP访问控制(CORS)
  • 02_SimpleTrigger
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • Angular Elements 及其运作原理
  • gcc介绍及安装
  • isset在php5.6-和php7.0+的一些差异
  • Java新版本的开发已正式进入轨道,版本号18.3
  • mysql常用命令汇总
  • Netty 4.1 源代码学习:线程模型
  • SpiderData 2019年2月25日 DApp数据排行榜
  • vue.js框架原理浅析
  • Vue2.x学习三:事件处理生命周期钩子
  • 爱情 北京女病人
  • 从PHP迁移至Golang - 基础篇
  • 记一次和乔布斯合作最难忘的经历
  • 批量截取pdf文件
  • 前端设计模式
  • 数组大概知多少
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 应用生命周期终极 DevOps 工具包
  • 怎样选择前端框架
  • linux 淘宝开源监控工具tsar
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​configparser --- 配置文件解析器​
  • ​Python 3 新特性:类型注解
  • ​马来语翻译中文去哪比较好?
  • #QT(串口助手-界面)
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (02)vite环境变量配置
  • (04)odoo视图操作
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (二)构建dubbo分布式平台-平台功能导图
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • .NET 常见的偏门问题
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NetCore部署微服务(二)
  • .NET和.COM和.CN域名区别
  • .NET开发者必备的11款免费工具
  • .net连接MySQL的方法