我书面方式这篇文章中的连接上下文的JIT产生的x86输出到Deep understanding of volatile in Java分析中的挥发性
public class Main {
private int x;
private volatile int g;
public void actor1(){
x = 1;
g = 1;
}
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
现在,我分析了上面这段代码生成了什么JIT。从我们在我以前的帖子讨论中,我们知道,输出1, 0
是不可能的,因为:
写挥发性v
使每一个动作a
前述v
导致该a
将是可见的(将被刷新到内存)v
之前将可见。
.................(I removed not important body of method).....
0x00007f42307d9d5e: c7460c01000000 (1) mov dword ptr [rsi+0ch],1h
;*putfield x
; - package.Main::[email protected] (line 14)
0x00007f42307d9d65: bf01000000 (2) mov edi,1h
0x00007f42307d9d6a: 897e10 (3) mov dword ptr [rsi+10h],edi
0x00007f42307d9d6d: f083042400 (4) lock add dword ptr [rsp],0h
;*putfield g
; - package.Main::[email protected] (line 15)
0x00007f42307d9d72: 4883c430 add rsp,30h
0x00007f42307d9d76: 5d pop rbp
0x00007f42307d9d77: 850583535116 test dword ptr [7f4246cef100h],eax
; {poll_return}
0x00007f42307d9d7d: c3 ret
难道我理解正确的话,它的作品,因为86不能让StoreStore
重新排序?如果可能的话,将需要额外的内存屏障,是吗?
EDITED优秀@尤金的答案AFTER:
int tmp = i; // volatile load // [LoadStore] // [LoadLoad]
在这里,我看你是什么均值很明显:every action below (after)
性读(int tmp = i
)不会重新排序。
// [StoreLoad] -- this one int tmp = i; // volatile load // [LoadStore] // [LoadLoad]
在这里,你放多了一个障碍。它确保我们不会对int tmp = i
重新排序。但是,为什么它很重要?为什么我有疑问?从我所知道的volatile load
保证:
每个行动后挥发性负载将不会被重新排序之前,易失性负载是可见的。
我看你写的:
需要有一个顺序一致性
但是,我不明白为什么需要顺序一致性。
什么'a'?什么'V'?你的意思是'x'和'g'? – Andreas
现在,'a'是'v'上的任何动作 - 例如它是一个动作:'x = 1'。 'v'是一个商店:'g = 1' – Gilgamesz
JMM不是为x86或任何其他特定的体系结构而制作的,并且在加载或存储方面没有任何理由。 JVM有责任按照每个体系结构上的指令来实现JMM。 – assylias