知识卡片
屏障约束重排
内容
重排序能提升执行效率,但多线程共享可变数据时会破坏”因果直觉”——书中 x=8; flag=true; 与 if(flag){print(x)} 例子说明,无同步机制时 show() 仍可能打印出 0。内存屏障(读/写/全屏障)给编译器和 CPU 划线:屏障前指令须先执行完,屏障后须后执行,并强制缓存刷回主存。volatile、锁释放获取本质都借助屏障建立可见顺序。
参考来源
- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第4章《可见性与有序性的原理》4.4.3节《硬件层面的内存屏障》(源文件:_epub-src/OEBPS/Text/chapter135.xhtml)
- 结论依据:原文用 ReorderDemo3 示例说明 update() 中 x=8 和 flag=true 若发生重排序,show() 方法可能读到 x=0 这一违反直觉的结果;随后给出读/写/全屏障三类硬件内存屏障的定义与作用,并说明加上 volatile 后 JVM 会插入内存屏障禁止该重排序,因此推出本卡结论。
- 原始内容:插入一个硬件层的内存屏障相当于告诉CPU和编译器先于这个屏障的指令必须先执行,后于这个屏障的指令必须后执行……硬件层的内存屏障强制把高速缓存中的最新数据写回主存,让高速缓存中相应的脏数据失效。一旦完成写入,任何访问这个变量的线程将会得到最新的值。