[英]Why is specifying a synchronization object in the lock statement mandatory
我试图围绕lock语句中究竟发生的事情。
如果我理解正确,锁定语句是语法糖和以下......
Object _lock = new Object();
lock (_lock)
{
// Critical code section
}
...被翻译成大致类似的东西:
Object _lock = new Object();
Monitor.Enter(_lock);
try
{
// Critical code section
}
finally { Monitor.Exit (_lock); }
我已经使用了几次lock语句,并且总是创建一个私有字段_lock
,作为专用的同步对象。 我明白为什么你不应该锁定公共变量或类型。
但是为什么编译器也不会创建该实例字段呢? 我觉得事实上可能存在开发人员想要指定锁定内容的情况,但根据我的经验,在大多数情况下,这绝对没有兴趣,你只需要锁定! 那么为什么锁没有无参数过载?
lock()
{
// First critical code section
}
lock()
{
// Second critical code section
}
将被翻译成(或类似):
[DebuggerHidden]
private readonly object _lock1 = new object()
[DebuggerHidden]
private readonly object _lock2 = new object()
Monitor.Enter(_lock1);
try
{
// First critical code section
}
finally { Monitor.Exit(_lock1); }
Monitor.Enter(_lock2);
try
{
// Second critical code section
}
finally { Monitor.Exit(_lock2); }
编辑 :我显然不清楚多个锁定语句。 更新了包含两个锁定语句的问题。
需要存储锁的状态 。 是否输入。 这样可以阻止尝试进入同一个锁的另一个线程。
这需要一个变量。 只是一个非常简单的,一个普通的对象就足够了。
对这样一个变量的一个硬性要求是它是在任何lock语句使用它之前创建的。 试图在你提出的时候即时创建它会产生一个新问题,现在需要使用一个锁来安全地创建变量,这样只有进入锁的第一个线程才能创建它,而其他线程试图进入锁被锁定,直到它被创建。 这需要一个变量。 Etcetera,一个无法解决的鸡蛋问题。
在某些情况下,您需要两个不同的lock
,它们彼此独立。 意思是当一个“可锁定”的代码部分被锁定时,其他“可锁定”不应该被锁定。 这就是为什么有能力提供锁定对象 - 你可以将它们中的几个用于几个独立lock
为了使无变量的东西起作用,你必须要么:
此外,您还有一个问题,即决定这些应该是实例级还是静态级。
最后,我猜测语言设计者并不认为在一个特定情况下的简化值得在阅读代码时引入歧义。 线程代码(这是使用锁的原因)已经很难正确编写并验证。 让它变得更难将是一件不好的事情。
允许隐式锁定对象可能会鼓励使用单个锁定对象,这被认为是不好的做法。 通过强制使用显式锁对象,该语言鼓励您将锁命名为有用的东西,例如“countIncementLock”。
这样命名的变量不会鼓励开发人员在执行完全独立的操作时使用相同的锁对象,例如写入某种流。
因此,对象可以在一个线程上写入流,同时在另一个线程上递增计数器,并且这两个线程都不一定会相互干扰。
语言不能这样做的唯一原因是因为它看起来像是一种好习惯,但实际上是隐藏了一种不好的做法。
编辑:
也许C#的设计者不想要隐式锁变量,因为他们认为它可能会鼓励不良行为。
也许设计师根本没有想到隐式锁定变量,因为他们首先要考虑其他更重要的事情。
如果每个C#开发人员确切地知道他们写入lock()
时发生了什么,并且他们知道其含义,那么它就没有理由不存在,也没有理由说它为什么不应该按照你的建议工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.