gpt4 book ai didi

java - 带有两个同步块(synchronized block)的 DCL 损坏了?

转载 作者:行者123 更新时间:2023-12-01 21:59:27 27 4
gpt4 key购买 nike

我无法理解 A fix that doesn't work 中的以下代码片段。(我确实阅读了同一页上的解释)。

如果我们有 2 个同步块(synchronized block),这个 DCL 版本是如何损坏的?还是 Java5 之后不再适用?

// (Still) Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
Helper h;
synchronized(this) {
h = helper;
if (h == null)
synchronized (this) {
h = new Helper();
} // release inner synchronization lock
helper = h;
}
}
return helper;
}
// other functions and members...
}

最佳答案

无法保证将 helper 视为非 null 的线程能够看到 new Helper(); 所做的所有写入。所以你可以访问单例的损坏版本。您需要在线程中将 helper 视为非 null 来保证它在 h = new Helper( ); 完成。观察非 volatile 变量的变化并不能建立这样的关系,而这就是线程所做的全部事情。

稍微简单一点,Java 内存可见性模型的工作方式是两个线程各自执行一些操作,在两个线程执行的两个操作之间建立“发生在之前”/“发生在之后”的关系。这可以包括同步块(synchronized block)内的操作或对 volatile 变量的访问。

但是通过上面的代码,线程可以观察到 helpernull,然后继续访问由 new Helper()< 创建的对象。它不必访问 volatile 变量,也不必进入同步块(synchronized block)。因此,没有任何东西可以建立所需的“发生后”关系来确保它看到 new Helper() 所做的任何更改。

关于java - 带有两个同步块(synchronized block)的 DCL 损坏了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33821401/

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