gpt4 book ai didi

c# - 为什么这种双重检查锁定是正确的? (。网)

转载 作者:太空狗 更新时间:2023-10-29 20:28:37 28 4
gpt4 key购买 nike

我已经阅读了很多关于双重检查锁定的危险的文章,我会努力远离它,但话虽如此,我认为他们的阅读非常有趣。

我正在阅读 Joe Duffy 的这篇关于使用双重检查锁定实现单例的文章: http://www.bluebytesoftware.com/blog/PermaLink,guid,543d89ad-8d57-4a51-b7c9-a821e3992bf6.aspx

他似乎提出的(变体)解决方案是这样的:

class Singleton {
private static object slock = new object();
private static Singleton instance;
private static int initialized;
private Singleton() {}
public Instance {
get {
if (Thread.VolatileRead(ref initialized) == 0) {
lock (slock) {
if (initialized == 0) {
instance = new Singleton();
initialized = 1;
}
}
}
return instance;
}
}

我的问题是,这是否仍然存在写入被重新排序的危险?特别是这两行:

instance = new Singleton();
initialized = 1;

如果这些写入被反转,那么其他线程仍然可以读取 null。

最佳答案

我认为关键在链接文章 ( http://msdn.microsoft.com/en-us/magazine/cc163715.aspx#S5 ) 中。具体来说,MS 实现的 .NET 2.0 内存模型具有以下属性:

Writes cannot move past other writes from the same thread.

Duffy 提到在 IA-64 上做了大量工作来支持这一点:

We accomplish this by ensuring writes have 'release' semantics on IA-64, via the st.rel instruction. A single st.rel x guarantees that any other loads and stores leading up to its execution (in the physical instruction stream) must have appeared to have occurred to each logical processor at least by the time x's new value becomes visible to another logical processor. Loads can be given 'acquire' semantics (via the ld.acq instruction), meaning that any other loads and stores that occur after a ld.acq x cannot appear to have occurred prior to the load.

请注意,Duffy 还提到这是特定于 MS 的保证 - 它不是 ECMA 规范的一部分(至少在 2006 年撰写本文时)。所以,Mono 可能没那么好。

关于c# - 为什么这种双重检查锁定是正确的? (。网),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8350713/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com