转:C# lock用法
lock 的目的很明确:就是不想让别人使用这段代码,体现在多线程情况下,只允许当前线程执行该代码区域,其他线程等待直到该线程执行结束;这样可以多线程避免同时使用某一方法造成数据混乱。
一般定义如下:
private static readonly object obj = new object();
lock(obj)
{
'''代码块
}
MSDN给出:我们lock的一般是对象,不是数值和字符串。
1、为什么不能lock值类型
比如lock(1)呢?lock本质上Monitor.Enter,Monitor.Enter会使值类型装箱,每次lock的是装箱后的对象。lock 其实是类似编译器的语法糖,因此编译器直接限制住不能lock值类型。退一万步说,就算能编译器允许你lock(1),但是 object.ReferenceEquals(1,1)始终返回false(因为每次装箱后都是不同对象),也就是说每次都会判断成未申请互斥锁,这样 在同一时间,别的线程照样能够访问里面的代码,达不到同步的效果。同理lock((object)1)也不行。
2、Lock字符串
那么lock("xxx")字符串呢?MSDN上的原话是:
锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留”。 这意味着整个程序中任何给定字符串都只有一个实例,同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何 位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。
3、MSDN推荐的Lock对象
通常,最好避免锁定 public 类型或锁定不受应用程序控制的对象实例。例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于 对象)也可能导致问题。
而且lock(this)只对当前对象有效,如果多个对象之间就达不到同步的效果。
而自定义类推荐用私有的只读静态对象,比如:
private static readonly object obj = new object();
为什么要设置成只读的呢?这是因为如果在lock代码段中改变obj的值,其它线程就畅通无阻了,因为互斥锁的对象变了,object.ReferenceEquals必然返回false。
所以,使用lock应该注意以下几点:
1、如果一个类的实例是public的,最好不要lock(this)。因为使用你的类的人也许不知道你用了lock,如果他new了一个实例,并且对这个实例上锁,就很容易造成死锁。
2、如果MyType是public的,不要lock(typeof(MyType))。
3、永远也不要lock一个字符串。
原文地址:http://www.cnblogs.com/Janzen/p/5475519.html
转:C# lock用法的更多相关文章
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
- java5 Lock用法
锁是控制多个线程对共享资源进行访问的工具.通常,锁提供了对共享资源的独占访问.一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁.不过,某些锁可能允许对共享资源并发访问,如 ReadWri ...
- 多线程中lock用法的经典实例
多线程中lock用法的经典实例 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.它可以把一段代码定义为互斥段(critical section),互斥段在一 ...
- 一个线程中lock用法的经典实例
/* 该实例是一个线程中lock用法的经典实例,使得到的balance不会为负数 同时初始化十个线程,启动十个,但由于加锁,能够启动调用WithDraw方法的可能只能是其中几个 作者:http://h ...
- 单例模式 与lock用法
在之前没用lock之前:如果我实现单例模式:直接就是下面的代码: public class Singleton { private static Singleton instanc ...
- synchronized Lock用法
在介绍Lock与synchronized时,先介绍下Lock: public interface Lock { void lock(); void lockInterruptibly() throws ...
- C# lock用法
当我们使用线程的时候,效率最高的方式当然是异步,即各个线程同时运行,其间不相互依赖和等待.但当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源 ...
- 多线程的并发问题,lock用法
开启多个线程,每个线程中多次操作公共变量 using System; using System.Collections.Generic; using System.Linq; using System ...
- .net Lock用法(转)
lock就是把一段代码定义为临界区,所谓临界区就是同一时刻只能有一个线程来操作临界区的代码,当一个线程位于代码的临界区时,另一个线程不能进入临界区,如果试图进入临界区,则只能一直等待(即被阻止),直到 ...
随机推荐
- EventProcessor与WorkPool用法--可处理多消费者
单一的生产者,消费者有多个,使用WorkerPool来管理多个消费者: RingBuffer在生产Sequencer中记录一个cursor,追踪生产者生产到的最新位置,通过WorkSequence和s ...
- Andrew Ng机器学习课程笔记(三)之正则化
Andrew Ng机器学习课程笔记(三)之正则化 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7365475.html 前言 ...
- 自己实现IOC过程
阅读了<架构探险>这本书之后简单梳理一下自己实现IOC的基本流程 首先要自己定义一个注解 import java.lang.annotation.ElementType; import j ...
- Java中mongodb使用and和or的复合查询
在MongoDB的JAVA查询中对应这些问题 and查询 //条件 startsAt< curr and endsAt > curr long curr = new Date().getT ...
- C#Redis初识
前面博客写了nginx负载均衡,大致了解了下nginx,不过这都是2016年的,2017年的计划也列了,重要的是执行,最近在看RabbitMQ和redis,由于今天和小伙伴们一起去聚餐了,回来的比较晚 ...
- MVC使用jQuery.ajax()删除数据
jQuery.ajax()可以简写为$.ajax().以前有写过MVC删除的实现,如<MVC实现删除数据库记录> http://www.cnblogs.com/insus/p/336804 ...
- 如何让企业邮箱更安全之gmail yahoo hotmail 反垃圾邮件机制
一.雅虎.Gmail Domainkeys 是由雅虎公司推出的一项确保电子邮件来源的真实性和内容的完整性的技术,它能让电子邮件服务商确定某封信是否真实的来自某个域和帮助他们的用户免受“钓鱼欺诈邮件“的 ...
- 【Java并发编程】4、JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别
转自:http://blog.csdn.net/aitangyong/article/details/46472643 JDK7对JDK5中的J.U.C并发工具进行了增强,其中之一就是新增了Trans ...
- class文件打包成jar
电脑左下角“开始”——“运行”——输入cmd——cd+空格+clss文件所在文件夹的路径——jar+空格+-cf+空格+“jar包的名字”.jar+空格+*.class.好了...
- Java面试题—初级(9)
139. Java中的泛型是什么 ? 使用泛型的好处是什么? 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 好处: 1.类型安全,提供编译期 ...