首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步和易失性中的JMM

同步和易失性中的JMM
EN

Stack Overflow用户
提问于 2014-03-28 03:28:41
回答 2查看 289关注 0票数 1

很多次我看到像这样的建筑:

代码语言:javascript
复制
class OneTimeWriter {
    volatile Object o;

    void synchronized set(Object o) {
        if(this.o == null) this.o = o;
    }

    Object get() {
        return this.o;
    }
}

synchronized本身的开始/结束时,我们已经读取/写入了成员。那么,我们是否可以从o中删除volatile,因为synchronized本身就有发布/获取语义?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-28 03:30:17

除非get也是synchronized;否则,在设置者将非null的内容放入字段和get调用之间的关系之前,不会发生这种情况。

票数 1
EN

Stack Overflow用户

发布于 2014-03-28 03:35:08

同步不是绝对的;它总是相对于另一个操作。在synchronized块的情况下,同步是在同一对象上关闭一个synchronized块和打开后续块之间的同步。

因为您的get方法不使用synchronized,所以在它和set方法之间建立关系之前没有发生。由于重新排序,获取线程可以读取由setter输入的部分设置的对象。例如,如果放入("Foo", 123),则获取线程可以读取与状态(null, 123)相同的对象:123状态在那里,但"Foo"状态尚未写入(或刷新到该核心的内存,等等)。

除了synchronized块之外,在写入volatile字段和随后读取该字段之间还会发生另一种形式的同步。在这种情况下,在你需要的关系发生之前,这才是你所需要的。setter中的synchronized块只确保this.o不会设置两次,仅此而已。

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

https://stackoverflow.com/questions/22703646

复制
相关文章

相似问题

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