gpt4 book ai didi

java - 为什么java双重检查锁单例必须使用 volatile 关键字?

转载 作者:行者123 更新时间:2023-11-30 05:18:07 26 4
gpt4 key购买 nike

我见过一些类似的问题,但我仍然有一些困惑。
代码在这里:

private volatile static DoubleCheckSingleton instance;

private DoubleCheckSingleton() {}
public static DoubleCheckSingleton getInstance(){

if(instance==null){ //first

synchronized (DoubleCheckSingleton.class){

if(instance==null){ // second
instance=new DoubleCheckSingleton();
}

}

}

return instance;

}

在这个问题中Why is volatile used in double checked locking ,它表示如果没有 volatile 关键字,线程可能会在构造函数完成之前分配实例变量,因此另一个线程可能会看到半构造的对象,这可能会导致严重的问题。

但我不明白 volatile 是如何解决问题的。 Volatile 用于确保可见性,因此当线程 A 将半构造对象分配给实例变量时,其他线程可以立即看到更改,这使情况变得更糟。

volatile如何解决这个问题,请有人给我解释一下。谢谢!

最佳答案

a thread may assign the instance variable before the constuctor finishes

这实际上不是真的。分配就在代码示例中:

instance=new DoubleCheckSingleton()

显然,执行该赋值的线程不可能在构造函数调用返回之前执行该赋值。

问题是,当两个不同的线程在两个不同的处理器上运行且没有任何同步时,它们不一定会就分配发生的顺序达成一致。因此,即使线程 A 在分配实例之前分配了新对象的字段(在 new DoubleCheckSingleton() 调用内),线程 B 分配实例之前可能会发现这些分配是无序的。线程 B 可以在看到 new DobuleCheckSingleton() 所做的一些其他事情之前看到对 instance 的分配。

实例声明为 volatile 可以同步线程。 volatile 保证线程A在分配 volatile 变量之前所做的所有事情在线程B时对线程B可见获取 volatile 变量的值。

关于java - 为什么java双重检查锁单例必须使用 volatile 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60045133/

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