锁机制的可变范围

时间:2014-07-04 03:02:27

标签: c# locking

有人可以详细解释为什么锁定变量的范围很重要吗? 例如:

lock(variable){ //do something here ! }

在msdn中,它声明要避免锁定公共类型,最好锁定私有或私有静态类型。在锁定过程中,究竟是什么锁定?变量地址还是什么?

3 个答案:

答案 0 :(得分:3)

lock接受System.Object类型的实例。 System.Object的所有实例都在内存中包含一些隐藏字段,用于同步目的(让我们称之为ThreadId)。那么,当您使用某个对象调用lock时会发生什么? lock语句(实际上它是Monitor.Enter的语法糖)检查传递的对象是否在ThreadId字段中有什么内容,如果它没有任何内容,则会在其中放置一些标识符(就我记得的当前线程的id而言),在lock语句下输入代码块,并在此块的末尾 - 重置ThreadId值。如果ThreadId字段不为空,它将停止并等待直到它变空。通过这种方式,可以保证只有一个线程可以使用相同的传递对象访问lock所涵盖的代码段。

为什么不建议在lock中使用公共属性/字段?使用锁定,很容易造成死锁(当线程A等待来自线程B的某些操作时,线程B又等待线程A的操作)。因此,控制在相同对象上进行的所有锁定非常重要。当你设计一些类时,你知道所有私有字段,只有你可以访问它们,只有你可以在锁中使用它们。一旦该领域成为公众,你将失去这种控制。是的,您仍然可以控制类中此字段周围的所有锁定,但您不知道该类的消费者将如何使用该字段,它们也可以将其用于锁定,从而导致死锁。

答案 1 :(得分:2)

这个variable只是某种独特的标签。将其设为私有可以避免在其他地方使用相同的标记进行偶然锁定。

有关内部锁实现的一些评论可以在这里找到:

http://blogs.msdn.com/b/junfeng/archive/2004/02/18/75454.aspx

答案 2 :(得分:0)

如果锁定特定对象中的私有成员,则只锁定该实例。如果锁定静态字段,则会锁定对象的所有实例。