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

jmm-内存屏障

在Java内存模型(JMM)中,内存屏障(Memory Barrier)是一种同步机制,用于确保特定的内存操作顺序,并保证内存可见性。内存屏障通过阻止处理器和编译器对内存操作进行重排序,从而避免多线程编程中可能出现的内存可见性问题。

整体介绍

Java规范定义了几种类型的内存屏障,主要分为以下几类:

  1. LoadLoad屏障:在 Load1; LoadLoad; Load2 这样的序列中,确保 Load1 数据的装载先于 Load2 及所有后续装载指令的装载。这意味着在 LoadLoad 屏障之前的读操作必须在 LoadLoad 屏障之后的读操作之前完成。
  2. StoreStore屏障:在 Store1; StoreStore; Store2 这样的序列中,确保 Store1 的数据对其他处理器可见(刷新到主内存),先于 Store2 及所有后续存储指令的存储。即 StoreStore 屏障之前的写操作必须在 StoreStore 屏障之后的写操作之前完成并对其他处理器可见。
  3. LoadStore屏障:在 Load1; LoadStore; Store2 这样的序列中,确保 Load1 数据的装载先于 Store2 及所有后续存储指令的存储。也就是 LoadStore 屏障之前的读操作必须在 LoadStore 屏障之后的写操作之前完成。
  4. StoreLoad屏障:在 Store1; StoreLoad; Load2 这样的序列中,确保 Store1 的数据对其他处理器可见(刷新到主内存),先于 Load2 及所有后续装载指令的装载。这是最强大的内存屏障,因为它同时包含了写操作的完成和读操作的开始顺序保障,且会使处理器的高速缓存失效,强制从主内存读取数据。

表格对照

内存屏障类型指令序列示例作用
LoadLoad屏障Load1; LoadLoad; Load2保证 Load1 先于 Load2 及后续所有读操作完成
StoreStore屏障Store1; StoreStore; Store2保证 Store1 对其他处理器可见先于 Store2 及后续所有写操作
LoadStore屏障Load1; LoadStore; Store2保证 Load1 先于 Store2 及后续所有写操作完成
StoreLoad屏障Store1; StoreLoad; Load2保证 Store1 对其他处理器可见先于 Load2 及后续所有读操作,且强制从主内存读取数据

解析

  1. LoadLoad屏障
    • 目的:防止处理器将 LoadLoad 屏障之后的读操作重排序到屏障之前,确保读操作的顺序性。
    • 示例:假设在多线程环境下,一个线程先读取共享变量 a,然后通过 LoadLoad 屏障,再读取共享变量 b。如果没有 LoadLoad 屏障,处理器可能会尝试将对 b 的读取操作提前执行,但有了 LoadLoad 屏障,就保证了先读取 a,再读取 b
  2. StoreStore屏障
    • 目的:防止处理器将 StoreStore 屏障之后的写操作重排序到屏障之前,确保写操作对其他处理器的可见性顺序。
    • 示例:在一个线程中,先对共享变量 x 进行赋值,然后通过 StoreStore 屏障,再对共享变量 y 进行赋值。StoreStore 屏障保证了对 x 的赋值先对其他处理器可见,然后才是对 y 的赋值。
  3. LoadStore屏障
    • 目的:防止处理器将 LoadStore 屏障之后的写操作重排序到屏障之前的读操作之前,确保读操作先于写操作完成。
    • 示例:当一个线程先读取共享变量 m,然后通过 LoadStore 屏障,再对共享变量 n 进行赋值时,LoadStore 屏障保证了读取 m 的操作完成后,才会进行对 n 的赋值操作。
  4. StoreLoad屏障
    • 目的:这是最强大的内存屏障,它不仅防止了写操作和读操作的重排序,还保证了写操作完成后,后续的读操作能获取到最新的数据。因为它会使处理器的高速缓存失效,强制从主内存读取数据。
    • 示例:在一个线程中,先对共享变量 p 进行赋值,然后通过 StoreLoad 屏障,再读取共享变量 qStoreLoad 屏障保证了对 p 的赋值操作完成并对其他处理器可见后,才会读取 q,并且读取 q 时能获取到最新的值。

在Java中,volatile 关键字的实现就利用了内存屏障。对 volatile 变量的读操作相当于有一个 LoadLoadLoadStore 屏障,而写操作相当于有一个 StoreStoreStoreLoad 屏障,从而保证了 volatile 变量的可见性和禁止指令重排序的特性。同样,synchronized 关键字在进入和退出同步块时也会有类似内存屏障的效果,以确保同步块内操作的内存可见性和顺序性。

http://www.xdnf.cn/news/1085869.html

相关文章:

  • 力扣 hot100 Day37
  • JVM基础01(从入门到八股-黑马篇)
  • vscode配置gitlab仓库详细步骤
  • Transformer模型架构深度讲解
  • web渗透之指纹识别1
  • 前端开发常见问题
  • Java开发面试核心知识点解析:从Redis缓存到内存模型全面解读
  • C++学习笔记01(自学草稿)
  • DeepSeek 帮助自己的工作
  • Spring的Bean原型模式下的使用
  • Java创建型模式---原型模式
  • 【C语言】指针与回调机制学习笔记
  • 【Java安全】反射基础
  • RoboRefer:面向机器人视觉-语言模型推理的空间参考
  • Web后端开发-分层解耦
  • Playfun即将开启大型Web3线上活动,打造沉浸式GameFi体验生态
  • 【ElasticSearch实用篇-01】需求分析和数据制造
  • turborepo 如何解决git管理包过大的问题
  • 病虫害数据集
  • 「Windows/Mac OS」AIGC图片生成视频 ,webui + stable-diffusion环境部署教程
  • AI编程才刚起步,对成熟的软件工程师并未带来质变
  • 【学习笔记】大数定理,频率与概率,均值与期望的区别
  • 深入解析TCP:可靠传输的核心机制与实现逻辑(三次握手、四次挥手、流量控制、滑动窗口、拥塞控制、慢启动、延时应答、面向字节流、粘包问题)
  • Java 命令行参数详解:系统属性、JVM 选项与应用配置
  • PCA通过“找最大方差方向”实现降维,本质是用更少的变量捕捉原始数据的主要模式
  • 3S技术+ArcGIS/ENVI全流程实战:水文、气象、灾害、生态、环境及卫生等领域应用
  • 深度学习7(梯度下降算法改进)
  • 使用Ideal创建一个spring boot的helloWorld项目
  • TMC4361A 使用(未验证)
  • 如何排查服务器中已经存在的后门程序?