对多种方法使用相同的锁

到目前为止,我没有遇到任何问题使用相同的锁多种方法,但我想知道以下代码是否可能实际上有问题(性能?),我不知道:

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种方法和集合无关。

另外,如果这个lockObjlockObj例使用(在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()直到完成为止。 如果你添加更多锁定在同一对象实例上的代码,那么在某些时候你最终会得到一个有效的单线程应用程序。

共享锁可锁定其他不相关的调用

如果使用相同的锁,则锁定一个方法也会不必要地锁定其他方法。 如果他们根本不相关,那么这是一个问题,因为他们必须等待彼此。 他们不应该这样做。

瓶颈

当经常调用这些方法时,这可能会造成瓶颈。 使用单独的锁定它们将独立运行,但共享相同的锁定意味着它们必须等待锁定根据需要更频繁地释放(实际上是经常的三倍 )。

要创建线程安全的单例,请使用此技术 。
你不需要锁。

通常,每个锁应尽可能少地使用。
更多的方法锁定同一个东西,当你真的不需要时,你最终可能会等待它。