写在前面

前几时在写业务代码的时候,看到有用到lock这个方法的,而我竟然并不知道是做什么用的,所以查找了许多博客文章,弄懂了百分之七八十,在此做下笔记。

感谢博客 http://www.cnblogs.com/wolf-sun/p/4209521.html 的解说,该篇博客大部分内容源自于此。

lock

官方MSDN的说法:

lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。 如果其他线程尝试进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

lock 关键字在块的开始处调用 Enter,而在块的结尾处调用 Exit。 ThreadInterruptedException 引发,如果 Interrupt 中断等待输入 lock 语句的线程。

通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。

最经常使用的是下面的代码段:

private static readonly object objlock = new object();
lock (objlock )
{
//要执行的代码逻辑
}

对于为什么锁私有,我觉得博客 http://www.cnblogs.com/wolf-sun/p/4209521.html 上的一个例子写的很好:

以厕所为例,私有就好比,厕所的锁只有你能访问到,而且最好这把锁不会因为外力而有所改变,别人访问不到,这样才能保证你进去了,别人就进不去了,如果是公有的,就好比你蹲位小单间的锁不是安装在里面而是安装在外边的,别人想不想进就不是你所能控制的了,这样也不安全。

在多线程中,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。

lock是不能锁值类型。

lock(string)

string也是应用类型,从语法上来说是没有错的。

但是锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。

这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。

因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。

通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。

例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。

这可能导致死锁,即两个或更多个线程等待释放同一对象。

出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。

而且lock(this)只对当前对象有效,如果多个对象之间就达不到同步的效果。lock(typeof(Class))与锁定字符串一样,范围太广了。

写在最后

总结一下好了:

1、lock的是引用类型的对象,string类型除外。

2、lock推荐的做法是使用静态的、只读的、私有的对象。

3、保证lock的对象在外部无法修改才有意义,如果lock的对象在外部改变了,对其他线程就会畅通无阻,失去了lock的意义。

4、学海无涯,不断补充自己才是最重要的!努力吧

[C#学习笔记]lock锁的解释与用法的更多相关文章

  1. xv6学习笔记(5) : 锁与管道与多cpu

    xv6学习笔记(5) : 锁与管道与多cpu 1. xv6锁结构 1. xv6操作系统要求在内核临界区操作时中断必须关闭. 如果此时中断开启,那么可能会出现以下死锁情况: 进程A在内核态运行并拿下了p ...

  2. 【Ext.Net学习笔记】02:Ext.Net用法概览、Ext.Net MessageBus用法、Ext.Net布局

    Ext.Net用法概览 Ext.Net还是很强大,如果运用熟练可以极大的提高编程效率.如果你也要学习Ext.Net,原文博主推荐书籍:<Ext.Net Web 应用程序开发教程>,是英文的 ...

  3. Ext.Net学习笔记22:Ext.Net Tree 用法详解

    Ext.Net学习笔记22:Ext.Net Tree 用法详解 上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat=&q ...

  4. Ext.Net学习笔记23:Ext.Net TabPanel用法详解

    Ext.Net学习笔记23:Ext.Net TabPanel用法详解 上面的图片中给出了TabPanel的一个效果图,我们来看一下代码: <ext:TabPanel runat="se ...

  5. Redis学习笔记4-Redis配置具体解释

    在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redi ...

  6. Dynamic CRM 2013学习笔记(二)插件基本用法及调试

      插件是可与 Microsoft Dynamics CRM 2013 和 Microsoft Dynamics CRM Online 集成的自定义业务逻辑(代码),用于修改或增加平台的标准行为.也可 ...

  7. Ext.Net学习笔记10:Ext.Net ComboBox用法

    ComboBox是最常用的控件之一,它与HTML中的Select控件很像,但可以进行多选.自定义显示格式.分页等. ComboBox用法 <ext:ComboBox runat="se ...

  8. 学习笔记_J2EE_SpringMVC_03_注解配置_@RequestMapping用法

    @RequestMappingde的用法 摘要: 主要介绍注解@RequestMapping的用法 一.@RequestMapping 简介 在Spring MVC 中使用 @RequestMappi ...

  9. Oracle学习笔记七 锁

    锁的概念 锁是数据库用来控制共享资源并发访问的机制. 锁用于保护正在被修改的数据 直到提交或回滚了事务之后,其他用户才可以更新数据 对数据的并发控制,保证一致性.完整性.

随机推荐

  1. Island Transport

    Island Transport http://acm.hdu.edu.cn/showproblem.php?pid=4280 Time Limit: 20000/10000 MS (Java/Oth ...

  2. php5.4 trait 理解与学习

    Trait 是 php5.4引入的新特性,手册上说的一大段没看懂,这里直接来过来. Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制.Trait 为了减少单继承语言的限制,使开发人员 ...

  3. Loitor_产品(一)

    源码:https://github.com/loitor-vis/vi_sensor_sdk 注意:以下要一直在管理员权限 1.C++ 示例程序的编译步骤 先确认你的系统已经成功安装了OpenCV. ...

  4. 版本号比较函数-js

    面试前,让做的一个版本号比较函数. <script type="text/javascript"> var v1=prompt("请输入第一个版本号" ...

  5. geoserver 通过代码实现发布地图服务

    GeoServer:代码实现批量发布地图服务 利用GeoServer发布WCS服务,那么如果我有很多数据需要进行发布,这样利用GeoServer提供的UI界面进行操作显然很不显示.那能不能利用GeoS ...

  6. KBMMW 4.80.00 发布

    一大波更新来了. 4.80.00 March 30 2015 Important notes (changes that may break existing code)        ======= ...

  7. 2018.06.29 NOIP模拟 区间(前缀和差量)

    区间(interval.cpp) 时限:2000ms 空间限制:512MB [问题描述] 给出一个长度为 n 的序列 a[1]-a[n]. 给出 q 组询问,每组询问形如<x,y>< ...

  8. k8s容器挂载配置文件

    1.新建ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: test-conf namespace: default labels: na ...

  9. IntelliJ IDEA 2017版 SpringBoot的web项目补充

    一.注解        @SpringBootApplication:Spring Boot项目的核心注解,主要目的是开启自动配置.        @Configuration:这是一个配置Sprin ...

  10. Linux下Git安装及配置

    转载自:https://blog.csdn.net/u013256816/article/details/54743470:加了一些自己的注释. yum安装 这里采用的是CentOS系统,如果采用yu ...