关于 C# 的 lock

锁的本质 是互斥量.

互斥量可以通俗的这么理解.(本质不同,但表像是相同的,这样描述更易理解,使用上也不容易出错)

 

以一个以对象(指针)的值(指向地址)作为Key的集合作为基础.

所有线程在进入锁的时刻,

判断如果Key存在,

    线程挂起并进入等待队列.

否则

    线程进入锁,并添加Key到集合.

    线程执行结束,移除集合中的锁.

    唤醒挂起的等待队列.

 

MSDN规范

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

 

常见写法

lock (this)、lock (typeof (MyType))、lock(“lockKey")、lock(obj)

 

1 lock(this)

   代码效果:以this作为Key,那么此锁只对所有该实例存在线程生效.

   常见问题:new了2个this,则锁中可同时存在2个线程. 可能超出预期.

2 lock(typeof(MyType))

   代码效果:以type作为Key,此锁对整个可见MyType类型的程序集生效.

   常见问题:因为MyType的可访问级别较高(public),可能会在类外面加锁,从而导致预期的线程无法进入,从而挂起.

                而且对typeof(MyType)加锁的系统开销较大.可能会超出预期.

3 lock("lockKey")

   代码效果:以字符串所在地址作为Key,此锁对整进程生效.(因为C# 进程中所有字符串统一管理..)

   常见问题:任意代码位置的 lock("lockKey") 都会导致其他线程无法进入. 从而挂起. 这样可能会不符合设计人员的初衷.

 

4 lock(obj)

   代码效果:以obj所指向内容作为key, 此锁仅对 对obj可见的代码 生效.

   常见问题:如果obj为static,则锁是唯一锁,如果obj为成员变量,则锁为实例锁,等同于 lock(this).

 

 

结论:

   要根据实际情况使用lock... 自己决定要锁起来的代码范围. 除了第二种写法有明显问题,,其他3种写法都是正常的..

只要搞清楚锁定的范围和线程让代码达到自己的预期就可以了.

posted on 2011-11-05 10:25  Terry@  阅读(619)  评论(2编辑  收藏  举报

导航