gpt4 book ai didi

java - JAVA 中的双重检查锁定

转载 作者:行者123 更新时间:2023-11-30 03:53:18 25 4
gpt4 key购买 nike

阅读about DCL in Wikipedia ,我想知道 DCL 中的问题和建议的解决方案,或者换句话说,为什么是 volatile需要关键字吗?简而言之,这个问题是:在某些情况下,使用 DCL 可能会导致线程使用部分构造的对象。建议的解决方案(适用于 JAVA 5+):

// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
helper = result = new Helper();
}
}
}
return result;
}

// other functions and members...
}

现在,我的问题是为什么不删除 volatile来自助手?如果我错了,请纠正我,但如果你只是打破了这条线:helper = result = new Helper();至:

result = new Helper();
helper = result;

在这种情况下 helper在对象完成之前永远不会获得引用。不是这样吗?怎么样volatile做得更好吗?

编辑:假设此代码:

class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
result = new Helper();
result.someMethod();
helper = result;
}
}
}
return result;
}
}

如果初始化后的下一行不能保证完全初始化的对象,我无法调用它的方法。我可以吗?

最佳答案

如果省略 volatile ,编译器可以完全优化结果。这个额外的局部变量不会改变那么多。它节省了额外的负载,但修复竞争条件的是 volatile 关键字。

假设我们有以下代码片段:

public volatile Object helper;

public synchronized void initHelper() {
Object result = new Object();
helper = result;
}

它将被编译为以下伪程序集:

public synchronized void initHelper() {
Object result = Object.new();
result.<init>();
// result is now fully initialized
// but helper is still null for all threads
this.helper = result;
// now all threads can access fully initialized helper
}

如果删除 volatile ,编译器可以假设没有其他线程使用helper并重新排列代码以对其进行优化。它可能决定删除不必要的局部变量并产生以下输出:

public synchronized void initHelper() {
this.helper = Object.new();
// from now on other threads can access helper
this.helper.<init>();
// but it's fully initialized only after this line
}

如果您在initHelper中添加函数调用。编译器永远不会在初始化之前调用此调用。即使在单线程中,这也会改变程序的含义。但允许进行优化,这会破坏访问该字段的多线程代码。

关于java - JAVA 中的双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23853705/

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