1

我即将创建一个将用作全局应用程序配置的类。这个类应该是这样的:

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 属性线程也安全。

4

2 回答 2

2

除了 Brian Gideon 的回答:请记住,锁定对Cipher属性的访问不会限制对设置此属性的实例成员的访问。

如果您需要Cipher在多线程环境中以类似的方式对属性的值进行操作GlobalConfiguration.Current.Cipher.DoSomething(),请确保也锁定访问权限DoSomething()(从内部AesCipher)。或者AesCipher如果可以的话,最好是不可变的。

虽然它可能不适用于AesCipher具体,但这说明了“一般解决方案”。

于 2013-09-13T20:25:47.147 回答
1

不要使用静态_instanceLock锁对实例成员执行锁定,例如Cipher. 该_instanceLock锁旨在保护单例的创建。使用不同的锁在Cipher属性中执行锁定。避免将一把锁用于多种用途。不同的用途......不同的锁。

实际上,这通常是非常标准的建议。使用静态锁定机制意味着同一应用程序域中同一类的所有实例都必须竞争锁定。当没有静态成员被引用时,在实例属性中做这样的事情可能会产生很多不必要的锁争用。

另外,你真的需要在这里使用ReaderWriterLockSlim吗?在大多数情况下,它实际上比普通的 old 慢lock。更进一步,你真的需要使用双重检查锁定模式吗?有时它是适当的,有时它是矫枉过正的。查看Jon Skeet 在 C# 中的单例实现模式以获取更多信息。

于 2013-09-13T19:59:44.623 回答