首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步前更新内存?

同步前更新内存?
EN

Stack Overflow用户
提问于 2012-03-13 09:30:42
回答 2查看 174关注 0票数 0

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

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

代码语言:javascript
复制
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;
  }
}

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-13 09:45:21

比赛条件是:

  1. 线程A看到instance == NULL并运行此代码instance = new MySingleton();。对instance.
  2. Thread B的写入是可见的,但对MySingleton的写入还没有。
  3. 线程B看到instance != NULL并开始处理instance != NULLB,现在正在处理一个它看不到的对象。

使instance易失性解决了这个问题,因为JDK内存规范(如JDK5 )保证了对非易失性对象的写入不会因写入易失性对象而出现混乱。因此,任何看到instance != NULL的线程都必须看到实例本身。

票数 4
EN

Stack Overflow用户

发布于 2012-03-13 09:39:47

您必须声明它是不稳定的,否则不能保证两个对getInstance()的调用将返回同一个实例。

不能保证主内存将被访问,只有一个与缓存一致的值.也就是说,所有线程都会看到相同的值。

顺便说一句:你知道,它当然比需要的要复杂得多。你所需要的就是

代码语言:javascript
复制
public enum MySingleton {
     INSTANCE;
}

做同样的事。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9681407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档