原创

JMM

温馨提示:
本文最后更新于 2025年06月02日,已超过 375 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

JMM

JVM规范中视图定义一种Java内存模型(java Memory Model)JMM,来屏蔽掉各种硬件和操作系统的内存访问差异

,实现Java程序在各种平台下都能达到一致的内存访问效果。

原则

JMM的关键技术点事围绕多线程的原子性、可见性、有序性展开的

JMM三大特性

  • 可见性

指当一个线程修改了某个变量的值,其他线程是否能够立即知道该变更,JMM规定了所有的变量都存储在主内存中

不同线程间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。

共享变量变更过程

线程读取 主内存的共享变量到工作内存,修改工作内存的值后,再提交给主内存实现变更。

优点:提升CPU效率,串行语义一致

缺点:不保证多线程间的语义一致(可能产生“脏读”)。

  • 原子性
  • 指令重排序

为了提升性能,编译器和处理器通常会对指令序列进行重新排序。Java规范规定JVM线程内部维持顺序化语义,只要程序的最终结果与它顺序化执行的结果相等,那么指令的顺序可以与代码顺序不一致。

源代码=> 编译器优化的重排=>指令并行的重排=>内存系统的重排=>最终执行的指令

处理器在进行重排序时,必须考虑指令之间的数据依赖性

  • 有序性

happens-before:先行发生 原则

在JMM中,如果一个执行的结果需要对另一个操作可见性,或者 代码重排序,那么这两个操作之间必须存在happens-before(先行发生)原则。逻辑上的先后关系

happens-beforen保证可见性和有序性的约束



总原则:

  • 如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
  • 两个操作之间存在happens-before关系,并不意味着一定按照happens-before原则制定的顺序来执行,如果重排序之后的执行结果与happens-before关系执行的结果 一致,那么这种重排序并不非法。

happens-before之8条

  • 次序规则

一个线程内,按照代码的顺序写在前面的操作先行发生于写在后面的额操作。前一个操作的结果可以被后续的操作获取。

  • 锁定规则

一个unLock操作先行发生于后面(时间上的先后),对同一个锁的lock操作

  • volatile变量规则

对于一个volatile变量的写操作先行发生于后面对这个变量的读操作,前面的写对后面(时间上的后面)的读是可见的

  • 传递规则

如果操作A先行发生于操作B,操作B先行发生于操作C,则可以得出操作A先行发生于操作C

  • 线程启动规则

 Thread对象的start()方法先行发生于此线程的每一个动作

  • 线程中断规则
  1. 对线程interrupt()方法的调用发生于被中断线程的代码检测到中断事件的发生
  2. 可以通过Thread.interrupt()检测到是否发生中断。
  3. 先调用interrupt()方法设置过中断标志位,才能检测到中断发送
  • 线程终止规则

线程中的所有操作都先行发生于对此线程的终止检测,可以通过isAlive()等手段检测线程是否已经终止

  • 对象终结规则

一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始

对象没有完成初始化之前,不能调用finalize()方法的











正文到此结束