gpt4 book ai didi

java - 没有 final 修饰符,Initialization On Demand Holder 成语线程安全吗

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:04:55 25 4
gpt4 key购买 nike

我有一种预感,即使用 holder 惯用法而不将 holder 字段声明为 final 不是线程安全的(由于不变性在 Java 中的工作方式)。有人可以证实这一点(希望有一些消息来源)吗?

public class Something {
private long answer = 1;

private Something() {
answer += 10;
answer += 10;
}

public int getAnswer() {
return answer;
}

private static class LazyHolder {
// notice no final
private static Something INSTANCE = new Something();
}

public static Something getInstance() {
return LazyHolder.INSTANCE;
}

}

编辑:我绝对想要来源声明,而不仅仅是像“它有效”这样的断言——请解释/证明它是安全的

EDIT2:为了让我的观点更清楚一点,我做了一点修改——我能确定 getAnswer() 方法将返回 21 而不管调用线程吗?

最佳答案

class initialization procedure保证如果使用静态初始值设定项(即 static variable = someValue;)设置静态字段的值,则该值对所有线程可见:

10 - If the execution of the initializers completes normally, then acquire LC, label the Class object for C as fully initialized, notify all waiting threads, release LC, and complete this procedure normally.


关于您的编辑,让我们想象一下有两个线程 T1 和 T2 的情况,从挂钟的角度来看按该顺序执行:

  • T1:Something s = Something.getInstance();
  • T2: Something s = Something.getInstance(); i = s.getAnswer();

那么你有:

  • T1获取LC,T1运行Something INSTANCE = new Something();,初始化answer,T1释放LC
  • T2 尝试获取 LC,但已被 T1 锁定 => 等待。当T1释放LC时,T2获得LC,读取INSTANCE然后读取answer

因此,由于 LC 锁,您可以看到在对 answer 的写入和读取之间有一个正确的先行发生关系。

关于java - 没有 final 修饰符,Initialization On Demand Holder 成语线程安全吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20995036/

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