[英]JMM in synchronized and volatile
Many times I saw constructions like this one: 我多次看到这样的结构:
class OneTimeWriter {
volatile Object o;
void synchronized set(Object o) {
if(this.o == null) this.o = o;
}
Object get() {
return this.o;
}
}
We have read/write membars at the begining/end of synchronized
itself. 在
synchronized
本身的开始/结束时,我们已读取/写入成员。 So, can we remove volatile
from o, since synchronized
has release/acquire semantics itself? 那么,由于
synchronized
具有发布/获取语义本身,我们可以从o中除去volatile
吗?
Not unless get
is also synchronized
; 除非
get
也synchronized
; otherwise, there's no happens-before relationship between the setter putting something non- null
into the field and the get
call. 否则,在setter中将非
null
放入字段和get
调用之间就没有事前发生的关系。
Synchronization isn't absolute; 同步不是绝对的。 it's always relative to another action.
它总是与另一个动作有关。 In the case of a
synchronized
block, the synchronization is between the closing of one synchronized
block and the opening of a subsequent one on the same object. 对于
synchronized
块,同步是在同一对象上一个synchronized
块的关闭与下一个synchronized
块的打开之间。
Since your get
method doesn't use synchronized
, there is no happens-before relationship established between it and the set
method. 由于您的
get
方法不使用synchronized
,因此它与set
方法之间没有建立事前关系。 The getting thread could read a partially-set object put in by the setter, due to reorderings. 由于重新排序,获取线程可以读取设置器放置的部分设置的对象。 For instance, if you put in
("Foo", 123)
, the getting thread could read that that same object as having state (null, 123)
: the 123
state is there, but the "Foo"
state hasn't yet been written (or flushed to this core's memory, etc). 例如,如果您放入
("Foo", 123)
,则获取线程可以读取与具有状态(null, 123)
相同的对象: 123
状态存在,但"Foo"
状态尚未存在写入(或刷新到该内核的内存等)。
Besides the synchronized
block, another form of synchronization happens between the writing of a volatile
field and the subsequent reading of that same field. 除
synchronized
块外,另一种形式的同步发生在volatile
字段的写入与该字段的后续读取之间。 That — and only that — is what provides the happens-before relationship you need in this case. 在这种情况下,只有(这)才可以提供您需要的事前关系。 The
synchronized
block in the setter only makes sure that this.o
isn't set twice, nothing more. 设置器中的
synchronized
块仅确保this.o
未被设置两次,仅此而已。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.