内存屏障,写屏障和读屏障

简介: 本文介绍了Java内存模型(JMM)的关键概念,包括主内存、工作内存、原子性操作、可见性和有序性,并详细解释了写屏障和读屏障的作用,它们是用来确保多线程环境中内存可见性和指令重排序一致性的同步操作。

jmm:

Java 内存模型(Java Memory Model,简称 JMM)是一种规定了多线程环境中共享变量的访问规则的模型。它确保了在不同线程之间的可见性、有序性和原子性。以下是关于 Java 内存模型的一些关键概念:

  1. 主内存(Main Memory):

    • 主内存是所有线程共享的内存区域,用于存储变量的值。所有线程都可以访问主内存中的变量。
  2. 工作内存(Working Memory):

    • 每个线程都有自己的工作内存,用于存储主内存中的变量的副本。线程只能直接在工作内存中读写变量,不能直接读写主内存。
  3. 读操作和写操作:

    • 当线程需要使用变量的值时,它会从主内存中读取变量的值到自己的工作内存。当线程修改变量的值时,它会先修改自己工作内存中的副本,然后再将修改后的值写回主内存。
  4. 原子性操作:

    • JMM 确保了基本数据类型(如 int 和 long)的读取和赋值操作是原子性的。这意味着在一个线程执行读或写操作期间,其他线程不能中断或看到中间状态。
  5. 可见性:

    • JMM 确保了一个线程对变量的修改对其他线程是可见的。这是通过在写操作时将变量的修改值刷新到主内存,以及在读操作时从主内存重新加载变量的值来实现的。
  6. 有序性:

    • JMM 确保了程序执行的顺序不会受到编译器优化、处理器的乱序执行等因素的影响。通过在指令序列中插入特定的内存屏障来实现有序性。
  7. 内存屏障(Memory Barriers):

    • 内存屏障是指令序列中的一种特殊指令,它能够禁止在屏障之前和之后的指令被重排序。在多线程环境中,内存屏障用于确保执行顺序的一致性。就是我们下面的读屏障和写屏障 0.0

Java 内存模型的设计旨在在多线程环境中提供一致的、可预测的内存访问行为,以确保程序的正确性和稳定性。理解 JMM 对于开发多线程应用程序非常重要,以避免出现并发性问题和线程安全性问题。

写屏障和读屏障

写屏障和读屏障是Java内存模型(JMM)中的概念,用于确保线程之间的内存可见性和指令重排序的一致性。下面我会分别解释它们的作用:

  1. 写屏障(Write Barrier)

    • 写屏障是一个同步操作,确保在写入操作之后,所有的修改都会立即被刷新到主内存中,以确保其他线程能够看到这些修改。
    • 在Java中,volatile变量的写入操作会插入写屏障,这意味着当一个线程写入一个volatile变量时,会立即将所有的修改刷新到主内存中,而不会将写入操作延迟到其他指令之后。
    • 写屏障可以保证写入操作的内存可见性,防止写入操作被重排序到后面的读取操作之前。
  2. 读屏障(Read Barrier)

    • 读屏障是一个同步操作,确保在读取操作之前,所有的数据都是最新的,即从主内存中读取最新的数据,而不是从线程的本地缓存中读取。
    • 在Java中,对volatile变量的读取操作会插入读屏障,这意味着当一个线程读取一个volatile变量时,会从主内存中获取最新的值,而不是使用线程本地缓存中的值。
    • 读屏障可以保证读取操作的内存可见性,防止读取操作将后续的写入操作重排序到前面。
目录
相关文章
|
3月前
|
存储 缓存 编译器
Linux源码阅读笔记06-RCU机制和内存优化屏障
Linux源码阅读笔记06-RCU机制和内存优化屏障
|
4月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
288 14
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
379 0
|
26天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
55 1
|
1月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
42 4
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储
|
1月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储