[英]When should I lock a static instance in multithreaded singletons when using a setter?
[英]Singletons and instance lock on properties
我将创建一个将用作全局应用程序配置的类。 该类应如下所示:
public class GlobalConfiguration
{
private static volatile GlobalConfiguration _current;
private static ReaderWriterLockSlim _instanceLock = new ReaderWriterLockSlim();
public ICipher Cipher {get;set;}
public IHasher Hasher {get;set;}
//....
public static GlobalConfiguration Current
{
get
{
if (_current == null)
{
_instanceLock.EnterWriteLock();
if (_current == null) _current = new GlobalConfiguration();
_instanceLock.ExitWriteLock();
}
return _current;
}
}
}
现在,我希望能够执行以下操作:
GlobalConfiguration.Current.Cipher = new AesCipher();
我现在担心的是,即使我的GlobalConfiguration类设计为单例,Cipher属性也会发生什么? _instanceLock用于GlobalConfiguration类,但是我不确定如何使用它使Cipher属性线程安全。
除了Brian Gideon的回答:还请记住,锁定对Cipher
属性的访问并不限制对实例成员的访问,该实例的成员对此属性进行了设置。
如果您需要以GlobalConfiguration.Current.Cipher.DoSomething()
类的方式在多线程环境中对Cipher
属性的值进行操作,请确保也锁定对DoSomething()
访问(从AesCipher
内部)。 或者,如果可以的话,最好使AesCipher
不可变。
尽管它可能不适用于AesCipher
,但它说明了“一般解决方案”。
不要使用静态_instanceLock
锁定对实例成员(例如Cipher
执行锁定。 _instanceLock
锁旨在保护单例的创建。 使用其他锁来执行Cipher
属性的锁定。 避免将一把锁用于多种用途。 不同的目的...不同的锁。
实际上,通常这是相当标准的建议。 使用静态锁定机制将意味着同一应用程序域中相同类的所有实例都必须竞争该锁定。 在没有引用静态成员的情况下在实例属性中执行此类操作可能会产生很多不必要的锁争用。
另外,您真的需要在此处使用ReaderWriterLockSlim
吗? 在大多数情况下,它实际上比普通的旧lock
慢。 更进一步,您是否真的需要使用双重检查的锁定模式。 有时候它是适当的,有时候是过度的。 有关更多信息,请查看C#中Jon Skeet的单例实现模式 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.