很多次我看到像这样的建筑:
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本身就有发布/获取语义?
发布于 2014-03-28 03:30:17
除非get也是synchronized;否则,在设置者将非null的内容放入字段和get调用之间的关系之前,不会发生这种情况。
发布于 2014-03-28 03:35:08
同步不是绝对的;它总是相对于另一个操作。在synchronized块的情况下,同步是在同一对象上关闭一个synchronized块和打开后续块之间的同步。
因为您的get方法不使用synchronized,所以在它和set方法之间建立关系之前没有发生。由于重新排序,获取线程可以读取由setter输入的部分设置的对象。例如,如果放入("Foo", 123),则获取线程可以读取与状态(null, 123)相同的对象:123状态在那里,但"Foo"状态尚未写入(或刷新到该核心的内存,等等)。
除了synchronized块之外,在写入volatile字段和随后读取该字段之间还会发生另一种形式的同步。在这种情况下,在你需要的关系发生之前,这才是你所需要的。setter中的synchronized块只确保this.o不会设置两次,仅此而已。
https://stackoverflow.com/questions/22703646
复制相似问题