当前位置: 首页 > news >正文

Java内存模型,内存屏障是干嘛的?

目录

Java 内存模型(Java Memory Model,JMM)

1. 定义和目的

2. 内存结构

3. 三大特性

4. happens-before 原则

内存屏障(Memory Barrier)

1. 定义和作用

2. 分类

3. 在 Java 中的应用

Java 内存模型(Java Memory Model, JMM)

1. 核心概念

2. 内存交互规则

3. 可见性

4. 有序性

5. 原子性

内存屏障(Memory Barrier)

1. 作用

2. 类型

3. 在 Java 中的应用

4. 示例

总结


Java 内存模型(Java Memory Model,JMM)

1. 定义和目的

Java 内存模型(JMM)是 Java 虚拟机规范中定义的一种抽象概念,它屏蔽了各种硬件和操作系统的内存访问差异,保证了 Java 程序在不同的硬件和操作系统平台上都能达到一致的内存访问效果,主要目的是为了确保多线程程序中数据的可见性、原子性和有序性,从而避免出现数据竞争和不一致的问题。

2. 内存结构

JMM 将内存分为主内存和工作内存:

  • 主内存:是所有线程共享的内存区域,存储了所有的共享变量,如实例变量、静态变量等。
  • 工作内存:每个线程都有自己独立的工作内存,线程对共享变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接操作主内存中的变量。线程在工作内存中会拷贝一份主内存中共享变量的副本,操作完成后再将结果刷新回主内存。
3. 三大特性
  • 原子性:指一个操作是不可中断的,要么全部执行成功,要么全部不执行。在 Java 中,对基本数据类型的变量的读取和赋值操作是原子性的,但像 i++ 这种复合操作不是原子性的。可以使用 synchronized 关键字或 Atomic 类来保证操作的原子性。
  • 可见性:当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。由于线程有自己的工作内存,可能会导致一个线程修改了共享变量的值,但其他线程没有及时从主内存中读取到最新的值。可以使用 volatile 关键字、synchronized 关键字或 Lock 来保证可见性。
  • 有序性:程序执行的顺序按照代码的先后顺序执行。但在 Java 中,为了提高性能,编译器和处理器可能会对指令进行重排序。重排序分为编译器重排序、指令级并行重排序和内存系统重排序。JMM 提供了 happens-before 原则来保证部分有序性,同时可以使用 volatile 关键字和 synchronized 关键字来禁止特定类型的重排序。
4. happens-before 原则

happens-before 原则是 JMM 中定义的一些规则,用于判断两个操作之间的执行顺序。如果操作 A happens-before 操作 B,那么操作 A 的结果对操作 B 是可见的,并且操作 A 会在操作 B 之前执行。常见的 happens-before 规则有:

  • 程序顺序规则:一个线程中的每个操作,happens-before 该线程中任意后续操作。
  • 监视器锁规则:对一个锁的解锁,happens-before 随后对这个锁的加锁。
  • volatile 变量规则:对一个 volatile 域的写,happens-before 任意后续对这个 volatile 域的读。
  • 传递性:如果 A happens-before B,且 B happens-before C,那么 A happens-before C。

内存屏障(Memory Barrier)

1. 定义和作用

内存屏障,也称为内存栅栏,是一种 CPU 指令,用于控制特定条件下的重排序和内存可见性问题。在 JMM 中,内存屏障是实现 volatilesynchronized 等关键字语义的基础。其主要作用有两个:

  • 禁止指令重排序:编译器和处理器为了提高性能,可能会对指令进行重排序,但在某些情况下,重排序会影响程序的正确性。内存屏障可以告诉编译器和处理器在内存屏障前后的指令不能进行重排序,保证指令按照特定的顺序执行。
  • 保证内存可见性:内存屏障可以强制刷新处理器的缓存,使得一个线程对共享变量的修改能够及时被其他线程看到。当一个线程执行写操作

相关文章:

  • 2024年认证杯SPSSPRO杯数学建模A题(第二阶段)保暖纤维的保暖能力全过程文档及程序
  • 在nodejs中使用RabbitMQ(三)Routing、Topics、Headers
  • RocketMQ、RabbitMQ、Kafka 的底层实现、功能异同、应用场景及技术选型分析
  • Ubuntu 如何安装Snipaste截图软件
  • vue渲染函数用法示例
  • 【docker知识】快速找出服务器中占用内存较高的容器
  • 机试题——移动01字符串
  • Ubuntu20.04上搭建nginx正向代理提供上网服务
  • 【Elasticsearch】keyword分析器
  • 用vue3写一个好看的wiki前端页面
  • 如何在24GB的GPU上运行DeepSeek-R1-Distill-Qwen-32B
  • Django REST Framework:如何获取序列化后的ID
  • Unity中自定义协程的简单实现
  • linux 查看设备中的摄像头迅速验证设备号
  • 畅聊deepseek-r1,SiliconFlow 硅基流动注册+使用
  • 一文讲清前端热更新
  • npm 私服使用介绍
  • docker搭建redis-cluster
  • DeepSeek、Kimi、文心一言、通义千问:AI 大语言模型的对比分析
  • 多媒体软件安全与授权新范例,用 CodeMeter 实现安全、高效的软件许可管理
  • 纪念|古文字学泰斗裘锡圭:“还有很多事情要做”
  • 读图|展现城市品格,上海城市影像走进南美
  • 阿森纳被打得毫无脾气,回天无力的阿尔特塔只剩嘴硬
  • 金融监管总局:近五年民企贷款投放年平均增速比各项贷款平均增速高出1.1个百分点
  • “20后”比“60后”更容易遭遇极端气候事件
  • 多地跟进官宣下调公积金贷款利率,最低降至2.1%