深入理解Java虚拟机——JMM(Java内存模型)

本文深入探讨了Java内存模型(JMM)的必要性,源于CPU缓存一致性、处理器优化和指令重排等问题。JMM旨在确保并发编程中的原子性、可见性和有序性,通过限制优化和使用内存屏障解决并发问题。详细解析了JMM对内存的划分,线程间通信机制,特别是volatile关键字的作用和原理,以及happens-before原则确保跨线程内存可见性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、 为什么要有Java内存模型?

1.1、 CPU和缓存一致性

1. 缓存一致性问题出现的原因

CPU的执行速度和内存的读取速度差距越来越大,导致CPU每次操作内存都要耗费很多等待时间。为解决这个问题,早期的程序员大佬提出了 “CPU和物理内存上新增高速缓存” 。 将运算所需要的数据从主内存复制一份到CPU的高速缓存 中,当 CPU进行计算时就可以直接从高速缓存中读数据和写数据 了,当运算结束再将数据刷新到主内存就可以了。 在多核 CPU和多线程的情形 中,每个线程都有自己的缓存,关于同一个线程共享数据的缓存内容可能不一致 。

1.2、 处理器优化和指令重排

1. 处理器优化

为了 使处理器内部的运算单元能够被充分利用 , 处理器可能会对程序代码进行乱序执行处理 ,这就是 处理器优化 。

2. 指令重排

除了现在很多流行的处理器 会对代码进行优化乱序处理 ,很多编程语言的编译器也会有类似的优化,比如 Java 虚拟机的即时编译器(JIT)也会做指令重排 。

1.3、 并发编程带来的问题

1. 三大问题

原子性问题,可见性问题和有序性问题 。其实 就是上面讲的『缓存一致性』、『处理器优化』、『指令重排序』造成的 。

2. 并发编程保证数据安全需要满足的特性

  1. 原子性 :指的是在一个操作中CPU 不可以在中途暂停然后再调度, 要么不执行,要么就执行完成 。
  2. 可见性 :指的是 多个线程访问同一个变量 时,一个线程修改了这个变量的值, 其他线程能够立即看得到修改后的值 。
  3. 有序性 :指的是 程序执行的顺序按照代码的先后顺序执行 ,而不能瞎几把重排,导致程序出现不一致的结果。

1.4、 JMM诞生的原因

Java 为了保证并发编程中可以满足原子性、可见性及有序性 ,诞生出了一个重要的概念,那就是 Java内存模型 ,内存模型 定义了共享内存系统中多线程程序读写操作行为的规范 。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性, 它解决了 CPU 多级缓存、处理器优化、指令重排等导致的内存访问问题 , 保证了并发场景下的一致性、原子性和有序性 。

  • JMM 内存模型解决并发问题主要采用两种方式: 限制处理器优化 和 使用内存屏障 。

2、Java内存模型

2.1、JMM对内存的划分

1. JMM对内存的划分和工作运作规则

JMM规定了内存主要划分为 主内存和工作内存 两种。Java内存模型规定了 所有的变量都存储在主内存中 (此处的主内存与介绍物理硬件时提到的主内存名字一样,两者也可以类比,但物理上它仅是虚拟机内存的一部分)。每条线程还有自己的 工作内存(可与前面讲的处理器高速缓存类比) ,线程的工作内存中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值