案例
并不会跳出死循环,可以加关键词volatile
cpu并发缓存架构
因为内存的速率发展不快,cpu寄存器和缓存速率差不多
原子操作
硬件层面
缓存一致性协议MESI
开启后保证数据的可见性
线程2修改后立刻立刻写回到内存
cpu总线嗅探机制(监听)
嗅探到该变量被修改,使线程1的工作内存的值置为invalid,cpu要使用的时候需要重新从内存读
volatile底层原理
变量在汇编级别指令会加上lock前缀指令
重排序
as-if-serial语义
重排序遵循as-if-serial语义原则,即不管怎么重排序,(单线程)程序的执行结果不能被改变,编译器和处理器不会对存在数据依赖关系的操作做重排序
happens-before原则
锁原则
解锁必然发生在同一个锁加锁之前
volatile原则
volatile变量的写先发生于读,每次被线程访问时都强迫从主内存中读该变量的值,当该变量发生变化时,又会强迫将最新的值刷新到主内存。
单例模式双重检测锁DCL(DoubleCheckLock
多线程并发模式下都进入到sync代码行,一个线程初始化后其他线程仍然可能初始化所以需要第二层if check。
对象半初始化
但还需要加volatile关键词
比如单例模式中new 那一步指令可能重排序,返回了一个没有构造函数进行初始化的new出来的对象。
内存屏障
JVM规范定义的
比如hotspot底层c++实现方法:
不同的cpu硬件,hotspotJDK有不同的底层实现
Linux实现,应用汇编lock前缀指令,会在硬件提供内存屏障,lock前后指令均不会重排序。