Java线程内存模型跟CPU缓存模型类似,是基于CPU缓存模型来建立的,Java的线程内存模型是标准化的,屏蔽了底层不同计算机的区别。
JMM数据原子操作
- read(读取):从主内存读取数据
- load(载入):将主内存读取到的数据写入工作内存中
- user(使用):从工作内存读取数据来计算
- assign(赋值):将计算好的值重新赋值到工作内存中
- store(存储):将工作内存数据写入主内存
- write(写入):将store过去的变量值赋值给主内存中的变量
- lock(锁定):将主内存变量加锁,标识为线程独占状态
- unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
以该例子为例
public class test {
public static volatile boolean initFlag=false;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("waiting data ...");
while (!initFlag){}
System.out.println("success");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("perpareing data...");
initFlag=true;
System.out.println("perpare data end");
}
}).start();
}
}
底层大致流程
JMM缓存不一致问题
总线加锁(性能太低)
cpu从主内存读取数据到高速缓存,会在总线对这个数据加锁,这样其他cpu没法去读或写这个数据,直到这个cpu使用完数据释放锁之后其他cpu才能读取该数据,即将并行程序变为串行执行,性能低。
MESI缓存一致性协议
多个cpu从主内存读取同一个数据到各自的高速缓存,当其中 某个cpu修改了缓存里的数据,该数据会马上同步回主内存,其他cpu通过总线嗅探机制可以感知到数据的变化从而将自己缓存里的数据失效
volatile可见性底层实现原理
volatile缓存可见性实现原理
底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存(缓存行锁定)并回写到主内存中
IA-32架构软件开发者手册对lock指令的解释:
1.会将当前处理器缓存行的数据立即写回到系统内存。
2.这个写回内存的操作会引起在其他cpu里缓存了该内存地址的数据无效(MESI协议)
底层是c语言实现的 这个lock 关键字 中有一个锁 是加在store之前的 在完成write完成之后 解锁
即:共享变量值被修改之后 通过 汇编语言同步回主内存 经过主线的时候 会触发MESI缓存一致性协议 将其他线程的共享变量值 失效 去重新 read 共享变量值 同时 对主内存的赋值操作 加一把锁 放置 并发读 操作
原子性
public class volatiletest {
public static volatile int num=0;
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.length; i++) {
System.out.println(i);
threads[i]=new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j <1000; j++) {
incrase();
}
}
});
threads[i].start();
}
for (Thread thread : threads) {
thread.join();//执行完此线程之后 启动其他线程
}
System.out.println(num);
}
private static void incrase() {
num++;
}
}
可以看到 它的结果是不同的
因为会产生 结果的丢失
因为 只有write和store 操作是加锁的 其他操作是不加的
当 线程1自增1了之后 线程2 抢到时间片 执行全部操作 执行到store 的时候 经过总线 通过MESI缓存一致性协议 使线程1的共享变量值 失效 导致 部分结果的丢失
转载:https://blog.csdn.net/weixin_43790623/article/details/106140510