多线程-CPU多级缓存模型-Java缓存模型-可见性-原子性-有序性
2021-04-10 10:04:50 8 举报
多线程-CPU多级缓存模型-Java缓存模型-可见性
作者其他创作
大纲/内容
CPU频繁读写主内存性能慢,所以给CPU增加了多层缓存。把主内存的数据读取到缓存里,后面的读和写都是针对缓存来的
i=1
L1
CPU
volatile底层实现原理1:lock指令:对修饰的变量,执行写操作的时候,JVM发送一条lock指令给CPU,CPU在计算完之后会立即将这个值刷回主存,同时有MESI协议,各个CPU进行嗅探,看自己本地缓存的数据是否被别人修改2:内存屏障:禁止重排序
执行线程1指令
CPU缓存flag=0
执行线程2指令
主内存flag=0
执行线程3指令
read
L2
读取0
当使用了volatile关键字,就是实现MESI机制,保障了多线程修改变量时,其他线程能够感知到变化,读取到最新的值涉及:lock前缀指令和内存屏障
第2个线程已经把flag修改为1,但只是修改了CPU缓存的值,并没有刷到主内存。此时其他线程读取到的还是旧值0.这就是多下次可见性
计算机
读取加载
工作内存i=0》1
原子性
修改为1
编译器和指令器为了提高代码执行效率,会将指令重排序,但要遵守happens-before规则。volatile变量规则:先写再读。一定保障前面的代码不能排到后面去,后面的不能排到前面去
线程2i++
修改flag=1
解决上面这个问题方式:1总线加锁;2MESI缓存一致性协议,强制刷新主内存,cpu嗅探机制,可以知道缓存里的变量被其他线程修改了,就会把缓存里的变量过期失效,下次读取就去主内存读取;
有序性
可见性CPU缓存模型-》Java缓存模型(主内存-工作内存)
读取到缓存
CPU缓存flag=1
write i=1
工作内存 i=0>1
线程1i++
两个线程同时修改i的值,都加1,加了两次,应该得到2.但是由于不是原子操作,一个线程覆盖了另一个线程的值,得到了1.这个就是原子性问题
CPU缓存
主内存i=0
0 条评论
回复 删除
下一页