预备知识

CPU 缓存模型

CPU Cache 缓存的是内存数据用于解决 CPU 处理速度和内存不匹配的问题,内存缓存的是硬盘数据用于解决硬盘访问速度过慢的问题。

cpu-cache.png

指令重排序

为了提升执行速度/性能,计算机在执行程序代码的时候,会对指令进行重排序。

什么是指令重排序? 简单来说就是系统在执行代码的时候并不一定是按照你写的代码的顺序依次执行。

常见的指令重排序有下面 2 种情况:

Java 源代码会经历 编译器优化重排 —> 指令并行重排 —> 内存系统重排 的过程,最终才变成操作系统可执行的指令序列。

指令重排序可以保证串行语义一致,但是没有义务保证多线程间的语义也一致 ,所以在多线程下,指令重排序可能会导致一些问题。

JMM 相关概念

  1. 什么是 JMM? JMM(Java Memory Model)是Java内存模型,它**主要定义了对于一个共享变量,当另一个线程对这个共享变量执行写操作后,这个线程对这个共享变量的可见性。**JMM抽象了线程和主内存之间的关系,规定了从Java源代码到CPU可执行指令的转化过程中,与并发相关的原则和规范。它确保了在多线程环境下,对共享变量的操作能够保持一致性和可见性。
  2. 它解决了什么问题? JMM解决了多线程编程中的内存一致性问题。在多线程环境中,由于线程可能有自己的本地内存(如CPU缓存),这可能导致不同线程对共享变量的读写操作出现不一致的情况。JMM通过定义一系列规则,确保了在多线程环境下,对共享变量的修改能够被其他线程正确地看到,从而保证了程序的正确性和可移植性。
  3. 如何解决的? JMM通过定义了一系列同步操作(如lock、unlock、read、load、use、assign、store、write等)和同步规则,以及happens-before原则,来确保线程间的操作顺序和可见性。这些规则和原则限制了编译器和处理器对指令的重排序,以防止它们破坏多线程程序的正确性。例如,happens-before原则规定了操作之间的顺序关系,确保了在某些操作之后进行的操作能够看到之前操作的结果。

Java 内存区域和 JVM 有何区别?

这是一个比较常见的问题,很多初学者非常容易搞混。 Java 内存区域和内存模型是完全不一样的两个东西