[英]Using the same lock for multiple methods
到目前为止,我没有遇到任何问题使用相同的锁定多种方法,但我想知道以下代码是否可能实际上有问题(性能?),我不知道:
private static readonly object lockObj = new object();
public int GetValue1(int index)
{
lock(lockObj)
{
// Collection 1 read and/or write
}
}
public int GetValue2(int index)
{
lock(lockObj)
{
// Collection 2 read and/or write
}
}
public int GetValue3(int index)
{
lock(lockObj)
{
// Collection 3 read and/or write
}
}
无论如何,3种方法和集合都没有关系。
另外,如果这个lockObj
也lockObj
例使用(在Instance属性中)会有问题吗?
编辑:澄清我在Singleton类中使用相同锁对象的问题:
private static readonly object SyncObject = new object();
public static MySingleton Instance
{
get
{
lock (SyncObject)
{
if (_instance == null)
{
_instance = new MySingleton();
}
}
return _instance;
}
}
public int MyMethod()
{
lock (SyncObject)
{
// Read or write
}
}
这会引起问题吗?
如果方法与您所说的无关,则为每个方法使用不同的锁; 否则效率很低(因为没有理由让不同的方法锁定同一个对象,因为它们可以安全地同时执行)。
而且,似乎这些是锁定在静态对象上的实例方法 - 这是有意的吗? 我有一种感觉,这是一个错误; 实例方法应该(通常)只锁定实例字段。
关于Singleton设计模式:
虽然锁定对于那些人来说是安全的,但更好的做法是对字段进行延迟初始化,如下所示:
private static object sharedInstance;
public static object SharedInstance
{
get
{
if (sharedInstance == null)
Interlocked.CompareExchange(ref sharedInstance, new object(), null);
return sharedInstance;
}
}
这种方式更快一些(因为互锁方法更快,并且因为初始化延迟),但仍然是线程安全的。
通过使用相同的对象来lock
所有这些方法,您将序列化所有线程中对代码的所有访问 。
那就是......运行GetValue1()
代码将阻止不同线程中的其他代码运行GetValue2()
直到完成为止。 如果你添加更多锁定在同一个对象实例上的代码,那么在某些时候你最终会得到一个有效的单线程应用程序。
如果使用相同的锁,则锁定一个方法也会不必要地锁定其他方法。 如果他们根本不相关,那么这是一个问题,因为他们必须等待彼此。 他们不应该这样做。
当经常调用这些方法时,这可能会造成瓶颈。 使用单独的锁定它们可以独立运行,但共享相同的锁定意味着它们必须等待锁定根据需要更频繁地释放(实际上是经常的三倍 )。
要创建线程安全的单例,请使用此技术 。
你不需要锁。
通常,每个锁应尽可能少地使用。
更多的方法锁定同一个东西,当你真的不需要时,你可能最终会等待它。
好问题。 制作锁具的优点和缺点是粗粒度更粗粒度,一个极端是每个数据的单独锁定,另一个极端是整个程序的一个锁定。 正如其他帖子指出的那样,重用相同锁的缺点通常是你可能会获得更少的并发性(虽然它取决于具体情况,你可能不会得到更少的并发)。
但是,使用更多锁的缺点通常是更容易造成死锁。 有更多的方法来解决死锁,你所涉及的锁越多。 例如,在不同的线程中以相反的顺序同时获取两个锁是潜在的死锁,如果只涉及一个锁则不会发生这种死锁。 当然,有时您可以通过将一个锁分成两个来修复死锁,但通常更少的锁意味着更少的死锁。 还增加了拥有更多锁的代码复杂性。
通常,这两个因素需要平衡。 为方便起见,每个类使用一个锁是很常见的,如果它不会导致任何并发问题。 实际上,这样做是一种称为监视器的设计模式。
我想说最好的做法是为了简化代码而减少锁定,并在有充分理由的情况下进行额外的锁定(例如并发,或者更简单或修复死锁的情况)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.