gpt4 book ai didi

java - 同步之前更新内存?

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

Java 内存模型中提到:当线程退出同步块(synchronized block)作为释放关联监视器的一部分时,JMM 要求将本地处理器缓存刷新到主内存。同样,作为进入同步块(synchronized block)时获取监视器的一部分,本地缓存会失效,以便后续读取将直接进入主内存,而不是本地缓存。

那么为什么在该代码中我必须将实例声明为 volatile ,因为当第二个线程进入同步块(synchronized block)时将直接进入主内存?

public final class MySingleton {
private static MySingleton instance = null;
private MySingleton() { }
public static MySingleton getInstance() {
if (instance == null) {
synchronized (MySingleton.class) {
if (instance == null) {
instance = new MySingleton();
}
}
}
return instance;
}
}

我的意思是,当另一个线程进入同步块(synchronized block)并进行第二次检查时,它应该从主内存中更新,如上所述。

最佳答案

竞争条件是这样的:

  1. 线程 A 看到 instance == NULL 并正在运行此代码 instance = new MySingleton();。对 instance 的写入可见,但对 MySingleton 的写入尚未可见。

  2. 线程 B 看到instance != NULL 并开始处理实例。

  3. 线程 B 现在正在处理一个它看不到其构造的对象。

instance设置为 volatile 可以解决这个问题,因为从JDK5开始,JDK内存规范保证对非 volatile 对象的写入相对于对 volatile 对象的写入不会出现乱序。因此任何看到 instance != NULL 的线程都必须看到实例本身。

关于java - 同步之前更新内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9681407/

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