下閱讀對象的字段這個職位是閱讀後提出: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
是的,發佈實例並調用其構造函數並不總是原子的,除非您使對象安全發佈。 –