下阅读对象的字段这个职位是阅读后提出:https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#pitfall-semi-sync阅读对象的引用和JMM
class Box {
int x;
public Box(int v) {
x = v;
}
}
class RacyBoxy {
Box box;
public synchronized void set(Box v) {
box = v;
}
public Box get() {
return box;
}
}
和测试:
@JCStressTest
@State
public class SynchronizedPublish {
RacyBoxy boxie = new RacyBoxy();
@Actor
void actor() {
boxie.set(new Box(42)); // set is synchronized
}
@Actor
void observer(IntResult1 r) {
Box t = boxie.get(); // get is not synchronized
if (t != null) {
r.r1 = t.x;
} else {
r.r1 = -1;
}
}
}
笔者说,这是可能的,r.r1 == 0
。我同意 那。但是,我对一个解释感到困惑:
实际的故障来自事实,即读取对象的引用并读取对象的字段在内存模型下是不同的。
我同意
阅读对象的引用和阅读对象的字段是内存模型 下不同,但我不知道它是如何对结果产生影响。
请帮我理解它。
P.S.如果有人对@Actor
感到困惑。它只是意味着:在一个线程中运行。
那么,你的意思是? 第一个线程(actor)发布了引用,但对象没有初始化是。然后,观察者读取box('boxie.get()')的引用,并且引用不是'null',观察者读取't.x == 0'。 – Gilgamesz
是的,发布实例并调用其构造函数并不总是原子的,除非您使对象安全发布。 –