当前位置: 首页 > 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.lryc.cn/news/582151.html

相关文章:

  • MMaDA:多模态大型扩散语言模型
  • 边缘计算新底座:基于VPP+DPDK的开放智能网关
  • kafka总结
  • AI + 数据治理的趋势:让治理更智能、更敏捷
  • Web Worker:让前端飞起来的隐形引擎
  • 七牛云Java开发面试题及参考答案(60道面试题汇总)
  • 【C语言】指针与回调机制学习笔记
  • 1-Kafka介绍及常见应用场景
  • CAIDCP AI驱动安全专家认证将于8月正式上线,首期班开始报名
  • c++-引用(包括完美转发,移动构造,万能引用)
  • Qt中的坐标系
  • 算法————模拟算法
  • 机房运维篇(添加备份盘)加备份
  • mac中有多个java版本涉及到brew安装中,怎么切换不同版本
  • Playwright vs TestCafe 对象注入机制详解对比
  • Redis Tag 字段详解与最佳实践
  • 可扩展 Redis 查询引擎的最佳实践
  • 人工智能-基础篇-22-什么是智能体Agent?(具备主动执行和调优的人工智能产物)
  • DejaOS常见问题
  • (4)ROS2:moveit2的几个坑
  • 多通道采发仪VS系列 智能监测终端 工业级采发仪精准守护隧道边坡、水利大坝
  • 【Echarts】“折线+柱状”实现双图表-家庭用电量可视化【文章附完整代码】
  • 【SigNoz部署安装】Ubuntu环境部署SigNoz:Docker容器化监控的全流程指南
  • 御控网关如何实现MQTT、MODBUS、OPCUA、SQL、HTTP之间协议转换
  • HTTP 重定向
  • Camera相机人脸识别系列专题分析之十六:人脸特征检测FFD算法之libcvface_api.so数据结构详细注释解析
  • C++ -- string类的模拟实现
  • Day07- 管理并发和并行挑战:竞争条件和死锁
  • 【AI大模型入门指南】机器学习入门详解
  • 烟雾,火焰探测器