我们来看下多核多线程是如何执行 i+1操作的
主函数:i = i + 1;
cache1 : i = 1
cache2 : i = 1
线程1 : CPU1 main memory -> i -> cache1 [ i + 1 ] -> cache1 -> main memory
线程2 : CPU2 main memory -> i -> cache2 [ i ] -> cache2 一直拿着值是1 而cache1一直在更新缓存数据但是没有把缓存区的数据更新置主内存!
为了解决缓存不一致的情况:
1 给数据总线加锁!
总线:数据总线、地址总线、控制总线
LOCK# [同时只有一个cpu一个线程可以拿到锁!]
缺点: 串行化,导致线程执行变慢!
2 CPU高速缓存一致性协议
Intel 提出的协议:[ MESI ]
1 核心思想:
当CPU写入数据的时候,发现该变量被内存共享【存在副本】。会发出一个信号,通知其他线程该缓存无效!
JMM(java memory model)
3 并发编程:
1 原子性:
操作不能被中断![一个操作/多个操作 要么成功,要么全失败,不能因为其他因素中断]
2 可见性:
一个操作修改了变量,那么其他操作会看到该变量的新值!
3 有序性(顺序执行):
int i = 0;
boolean flag = false;
i = 1
flag = true;
重排序只要求最终一致性!