内存屏障与JVM并发
2010-05-11 00:00:00 来源:WEB开发网不出意外,synchronized生成的指令数量比volatile多。第18行做了一次增操作,但是JVM没有显式插入内存屏障。相反,JVM 通过在 第10行和第25行cmpxchg的lock前缀一石二鸟。cmpxchg的语义超越了本文的范畴。lock cmpxchg不仅原子性执行写操作,也会刷新等待的读写操作。写操作现在将在所有后续内存操作之前完成。如果我们通过 java.util.concurrent.atomic.AtomicInteger 重构和运行Counter,将看到同样的手段。
import java.util.concurrent.atomic.AtomicInteger;
class Counter{
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args){
for(int i = 0; i < 1000000; i++)
counter.incrementAndGet();
}
}
$ java -XX:+UnlockDiagnosticVMOptions -XX:PrintAssemblyOptions=hsdis-print-bytes -XX:CompileCommand=print,*AtomicInteger.incrementAndGet Counter
1 0x024451f7: push %ebp ;...55
2 0x024451f8: mov %esp,%ebp ;...8bec
3 0x024451fa: sub $0x38,%esp ;...83ec38
4 0x024451fd: jmp 0x0244520a ;...e9080000 00
5 0x02445202: xchg %ax,%ax ;...6690
6 0x02445204: test %eax,0xb771e100 ;...850500e1 71b7
7 0x0244520a: mov 0x8(%ecx),%eax ;...8b4108
8 0x0244520d: mov %eax,%esi ;...8bf0
9 0x0244520f: inc %esi ;...46
10 0x02445210: mov $0x9a3f03d0,%edi ;...bfd0033f 9a
11 0x02445215: mov 0x160(%edi),%edi ;...8bbf6001 0000
12 0x0244521b: mov %ecx,%edi ;...8bf9
13 0x0244521d: add $0x8,%edi ;...83c708
14 0x02445220: lock cmpxchg %esi,(%edi) ;...f00fb137
15 0x02445224: mov $0x1,%eax ;...b8010000 00
16 0x02445229: je 0x02445234 ;...0f840500 0000
17 0x0244522f: mov $0x0,%eax ;...b8000000 00
18 0x02445234: cmp $0x0,%eax ;...83f800
19 0x02445237: je 0x02445204 ;...74cb
20 0x02445239: mov %esi,%eax ;...8bc6
21 0x0244523b: mov %ebp,%esp ;...8be5
22 0x0244523d: pop %ebp ;...5d
更多精彩
赞助商链接