本文实例讲述了C#中lock的用法。分享给大家供大家参考。具体分析如下:
lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
先来看看执行过程,代码示例如下:
lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁。
lock-statement:(lock 语句:)
下列形式的 lock 语句:
一个类的 system.type 对象可以方便地用来当作关于该类的静态方法的互斥锁。例如:
接下来说一些该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。
而自定义类推荐用私有的只读静态对象,比如:
希望本文所述对大家的C#程序设计有所帮助。
新闻热点
疑难解答