1.CPU Cache模型
- 从内存中把数据读到Cache
- 在Cache中更新数据
- 把Cache中数据更新到内存
cpu缓存一致性问题
MESI()
读操作:不做任何事情,把Cache中的数据读到寄存器
写操作:发出信号通知其他的CPU将该变量的Cache line置为无效,其他的CPU要访问这个变量的时候,只能从内存中获取。
Cache line CPU的cache中会增加很多的Cache line
2. JMM模型
- 主内存数据所有线程都可以访问(共享变量)
- 每个线程都有自己的工作空间(本地内存)
- 工作空间:局部变量、主内存的副本
- 线程不能直接修改主内存的数据,只能将数据读到工作空间,修改完刷新到主内存
3. volatile关键字的语义分析
1. 保证可见性
对共享变量的修改,可以让其他线程感知到。
不能保证原子性。
保证可见性的原理:
使用lock锁;
当某个线程将volatile修饰的变量改变的时候,会将该变量的Cache line置为失效;
其他线程感知到Cache Line失效,会重新去主存获取该变量。
lock是汇编中的指令;
Cache line是硬件中的指令。
2. 保证有序性
重排序:
编译阶段、cpu指令优化阶段;
代码顺序并不是实际的执行顺序。
volatile的规则:
- volatile修饰的变量位置不变
- (即volatile前的代码不能放到volatile之后,volatile后的代码不能放到volatile之前)
保证有序性的原理:
加了轻量锁Lock
4. volatile与synchronized的区别
使用上的区别
volatile只能修饰变量,synchronized只能修饰方法和代码块
对原子性的保证
volatile不能保证原子性,synchronized可以保证原子性
对可见性的保证
都可以保证可见性
volatile使用lock锁(轻量锁),synchronized使用monitorEnter和monitorexit monitor JVM
对有序性的保证
都能保证有序性,synchronized使代码变成串行化
其他
volatile不会阻塞
synchronized会引起阻塞