CPU高速缓存
在介绍缓存一致性问题之前,要先了解CPU的高速缓存。
缓存一致性问题
CPU 高速缓存的引入导致了缓存一致性问题,CPU-0 读取主存的数据,缓存到 CPU-0 的高速缓存中,CPU-1 也做了同样的事情,而 CPU-1 把 count 的值修改成了 2,并且同步到 CPU-1 的高速缓存,但是这个修改以后的值并没有写入到主存中,CPU-0 访问该字节,由于缓存没有更新,所以仍然是之前的值,就会导致数据不一致的问题引发这个问题的原因是因为多核心 CPU 情况下存在指令并行执行,而各个 CPU 核心之间的数据不共享从而导致缓存一致性问题。
-
总线锁
当一个 CPU 对其缓存中的数据进行操作的时候,往总线中发送一个 Lock 信号。其他处理器的请求将会被阻塞,那么该处理器可以独占共享内存。总线锁相当于把 CPU 和内存之间的通信锁住了,所以这种方式会导致 CPU 的性能下降,所以 P6 系列以后的处理器,出现了另外一种方式,就是缓存锁。
-
缓存锁
如果缓存在处理器缓存行中的内存区域在 LOCK 操作期间被锁定,当它执行锁操作回写内存时,处理不在总线上声明 LOCK 信号,而是修改内部的缓存地址,然后通过缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域的数据,当其他处理器回写已经被锁定的缓存行的数据时会导致该缓存行无效。所以如果声明了 CPU 的锁机制,会生成一个 LOCK 指令,会产生两个作用。
- Lock 前缀指令会引起引起处理器缓存回写到内存,在 P6 以后的处理器中,LOCK 信号一般不锁总线,而是锁缓存。
- 一个处理器的缓存回写到内存会导致其他处理器的缓存无效。
线程的原子性、可见性、有序性问题,是我们抽象出来的概念,他们的核心本质就是刚刚提到的缓存一致性问题。
缓存一致性问题会导致可见性问题,处理器的乱序执行优化会导致原子性、有序性问题,为了解决这些问题,所以在 JVM 中引入了 JMM 的概念。