我写了这个简单的Java程序:
package com.salil.threads;
public class IncrementClass {
static volatile int j = 0;
static int i = 0;
public static void main(String args[]) {
for(int a=0;a<1000000;a++);
i++;
j++;
}
}
这将为i ++和j ++生成以下反汇编代码(除去了剩余的反汇编代码):
0x0000000002961a6c: 49ba98e8d0d507000000 mov r10,7d5d0e898h
; {oop(a 'java/lang/Class' = 'com/salil/threads/IncrementClass')}
0x0000000002961a76: 41ff4274 inc dword ptr [r10+74h]
;*if_icmpge
; - com.salil.threads.IncrementClass::main@5 (line 10)
0x0000000002961a7a: 458b5a70 mov r11d,dword ptr [r10+70h]
0x0000000002961a7e: 41ffc3 inc r11d
0x0000000002961a81: 45895a70 mov dword ptr [r10+70h],r11d
0x0000000002961a85: f083042400 lock add dword ptr [rsp],0h
;*putstatic j
; - com.salil.threads.IncrementClass::main@27 (line 14)
这是我对以下汇编代码的了解:
-lock add dword ptr [rsp],0h:锁定由堆栈指针rsp表示的内存地址,并向其添加0。
JMM指出,在每个易失性读取之前必须有一个加载内存屏障,而在每个易失性写入之后都必须有一个存储屏障。我的问题是:
最佳答案
英特尔处理器x86带有strong memory model。
因此,所有的屏障StoreStore,LoadLoad和LoadStore在x86上都不可用。
除StoreLoad外,可以通过 mfence或cpuid或锁定insn 实现。
您已经可以使用汇编代码进行确认。其他障碍仅意味着限制编译器的优化和转换,以免破坏java memory model spec。
当您在英特尔处理器上运行时,我假设它是x86。
请阅读
锁不是指令,而是指令的前缀(表现为storeLoad屏障)。