c# – 需要一个锁,需要一个非常不可变类型的懒惰初始化?
如果我有一个非常不可变的类型(所有成员都是只读的,如果它们是引用类型成员,那么它们也指的是不可变的对象).
我想在类型上实现一个懒惰的初始化属性,如下所示: private ReadOnlyCollection<SomeImmutableType> m_PropName = null; public ReadOnlyCollection<SomeImmutableType> PropName { get { if(null == m_PropName) { ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */; m_PropName = temp; } return m_PropName; } } 从我能说的: m_PropName = temp; …是线程安全的我不担心两个线程同时进行初始化,因为它将是罕见的,两个结果将从逻辑角度来看是一样的,如果我没有,我宁愿不使用锁至. 这会工作吗优缺点都有什么? 编辑: (答案似乎表明运行时不会允许这种情况发生.) 编辑: 基本上: private ReadOnlyCollection<SomeImmutableType> m_PropName = null; public ReadOnlyCollection<SomeImmutableType> PropName { get { if(null == m_PropName) { ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */; System.Threading.Interlocked(ref m_PropName,temp,null); } return m_PropName; } } 这应该是确保在此对象实例上调用此方法的所有线程将获得对同一对象的引用,因此==运算符将工作.有可能浪费工作??,这是很好的 – 它只是使这是一个乐观的算法. 如下面的一些评论中所指出的,这取决于.NET 2.0内存模型的工作原理.否则,m_PropName应声明为volatile. 解决方法
这将工作.写入C#中的引用保证是原子的,如
spec的5.5节所述.
这仍然可能不是一个好办法,因为您的代码将更加混乱调试和阅读,以换取对性能的一个小的影响. Jon Skeet在C#中执行singeltons有一个很好的page. 关于这样的小型优化的一般建议是不要这样做,除非分析器告诉你这个代码是一个热点.此外,您应该谨慎编写大多数程序员无法完全理解的代码,而无需检查规范. 编辑:正如注释中所指出的,即使你说你不介意如果你的对象的2个版本被创建,那么这种情况是非常直观的,这种方法不应该被使用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |