Lock:
        C#只能lock 引用类型的值,如果lock一个int, bool,编译器会报错。
    当一个互斥锁已被占用时,在同一线程中执行的代码仍可以获取和释放该锁。但是,在其他线程中执行的代码在该锁被释放前是无法获得它的。
    建议不要使用锁定对象类型之种方法来同步对静态数据的访问。您无权控制的其他代码可能也会锁定您的类类型。这可能导致死锁。因此,请使用锁定私有静态对象这种方法来同步对静态数据的访问。
    也就不是说不能写类似lock (typeof(this)) {} 的不规范语句。
旧事重提了,或许很多人会奇怪,为什么 C# 不允许lock一个struct ? 例如:
public void ProcessTask(int taskid){
    lock(taskid){  .....   }
}
编译说lock只能使用引用类型。有些人聪明(我想我以前也有这样的"聪明"。。),这样做: lock((object)taskid){...}
但是,实际的经验告诉我,这样行不通,lock需要的是引用,严格来说是需要对象的实例。
即使对象在意义上是相同的,但是如果不是ReferenceEquals的话,那么将作为两个实例来对待,那么C# lock 的就不是同一个东西。也就是说,当你以为这个 lock 生效的话,它其实在做无用工。
在上面的例子,由于lock((object)taskid)每执行一次,taskid都进行一次装箱,而装箱后的对象不是同一个实例(都是完完全全的新的实例),所以 lock((object)taskid){...} 是白做了。
当然,lock((object)123){} 这样的做法也是一样有问题的。
但是这种就好点:lock(“helloworld“){} 。为什么只是“好点”,而不是“没有问题”了呢。原因在于DotNet分配字符串的机制。DotNet为每个Assembly里的字符串都分配固定的空间。所以每次引用“helloworld“的时候,是同一个实例。但是这个字符串不会在其他Assembly中得到共用。如果几个Assembly都是这样写的,那么它们各自有她们自己的“helloworld“
比较好的做法:
lock(this)...
lock(typeof(ThisType))
lock(GetType())//除非你明白这是干什么,否则不要乱来。
lock(SomeType.StaticSyncObject)
lock(someinst.SyncObject)
其他的一些不好的做法
lock(“task:“+id)
lock(filename)
当然,具体lock什么东西,是设计上的协议和规范。不过要注意的是,使用lock必须明确对象是不是想象中的同一实例。
lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:
Object thisLock = new Object();
lock (thisLock)
{
// Critical code section
}
有关更多信息,请参见线程同步(C# 编程指南)。
备注
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
线程处理(C# 编程指南) 这节讨论了线程处理。
lock 调用块开始位置的 Enter 和块结束位置的 Exit。
通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
如果实例可以被公共访问,将出现 lock (this) 问题。
如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。
由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。
最佳做法是定义 private 对象来锁定, 或 private shared 对象变量来保护所有实例所共有的数据。

原文链接

C#只能lock 引用类型的值 (转载)相关推荐

  1. [转载]实际举例C#引用类型和值类型的区别

    http://www.cnblogs.com/coolbeibei/archive/2009/03/23/1419706.html 实际举例C#引用类型和值类型的区别 我们都知道,c#的两大数据类型分 ...

  2. 第五章 基元类型,引用类型和值类型

    目录 5.1 编程语言的基元类型 5.2 引用类型和值类型 5.3 值类型的装箱和拆箱 5.4 对象哈希码 5.5 dynamic基元类型 5.1 编程语言的基元类型 编译器直接支持的数据类型称为基元 ...

  3. Javascript高级程序设计——基本类型和引用类型的值

    ECMAScript中的变量有两种不同的数据类型的值: 基本类型:基本类型的值是简单的数据段.包括:Undefined.Null.Number.Boolean.String五种 引用类型:引用类型的值 ...

  4. .NET引用类型与值类型

    值类型和引用类型的基类 引用类型和值类型都继承自System.Object类.不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即直接继承System.Valu ...

  5. 基本类型和引用类型的值 函数的传递参数

    ECMAScript中函数的传参都是按值传递的. 不管是传基本类型的值还是引用类型的值都是按值传递,访问变量则分按值和按引用两种方式. 向参数传递基本类型的值 被传递的值会被复制(对应文章<基本 ...

  6. .net 基元类型,引用类型和值类型

    基元类型(primitive type): 编译器直接支持的数据类型称为基元类型(primitive type). string 与 String: 由于C#中的string (一个关键字)直接映射到 ...

  7. 【基础中的基础】引用类型和值类型,以及引用传递和值传递

    一直在博客园怼人,非常惭愧.所以郑重决定: 好好写一篇干货,然后再接着怼人. 这是一起帮上陈百万同学的求助,讲了一会之后,我觉得很有些普世价值,干脆就发到园子来.面向小白,高手轻拍. 我们从最简单的说 ...

  8. 第五章 基元类型、引用类型、值类型 CLR学习第五课

    一.基元类型:编译器直接支持的数据类型称为基元类型(如int类型其对于的是system.int32). 二.类型溢出,可以用checked 和unchecked进行类型溢出检查和不进行类型溢出检查.一 ...

  9. C#中 类和结构 值类型和引用类型以及 值传递和引用传递

    类: 概念就不赘述了. 结构: 1>它是从System.Object派生.但不能从别的类中派生,也不能从别的结构中继承. 2>它是一个值类型.呵呵. 3>里面还能写方法和字段, 如: ...

最新文章

  1. hadoop 基础环境搭建(一)
  2. VTK:可视化算法之Cutter
  3. CF626E. Simple Skewness
  4. nginx post请求超时_nginx记录分析网站响应慢的请求(ngx_http_log_request_speed)
  5. 计算机怎样连接网络适配器,win10 本地连接共享internet时, 会将承载网络适配器IP设置成192.168.137.1但不成功...
  6. 移植 Qt4.8.5到Tiny210
  7. python输出命令_Python中的命令输出解析
  8. 拓端tecdat|R语言中编写最小工作示例(MWRE)
  9. Visio PAD模板
  10. php 控制骰子概率,jQuery+PHP实现的掷色子抽奖游戏实例
  11. 火焰传感器与 Arduino 连接
  12. 线性代数计算器C语言(1)——计算行列式值
  13. 【檀越剑指大厂--网络安全】网络安全学习
  14. java开发抢红包算法,抢红包算法的实现-java
  15. 因果推断——现代统计的思想飞跃
  16. 开源框架springboot-mybatis-wr-separation实现springboot+mybatis读写分离
  17. 敲完第一万行代码我发现一个秘密
  18. MyBatis警告信息 All illegal access operations will be denied in a future release
  19. 鸟哥的Linux私房菜 命令笔记2
  20. 斯坦福大学计算机排名多少,斯坦福大学全球排名第几

热门文章

  1. 共用体和枚举,写写意思下
  2. 《编码:隐匿在计算机软硬件背后的语言(美)》读书笔记一
  3. jvm八:接口初始化规则
  4. docker 镜像的使用和下载
  5. 我对软件行业及大数据的理解
  6. Notepad++免费开源文本编辑器
  7. 深入理解IOC模式及Unity框架
  8. 五.Java IO、NIO、文件、通讯
  9. 负载均衡沙龙活动第二期现场问答汇集
  10. DataGridView新特色、常用操作