hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶

面试官:volatile 实现原理是什么?


volatile 关键字的实现原理
volatile 是 Java 中用于解决多线程环境下变量可见性和指令重排序问题的关键字。其实现原理基于 JVM 内存屏障(Memory Barriers)硬件层面的缓存一致性协议(如 MESI)。以下是详细分析:


1. 核心作用

  • 可见性:确保一个线程对 volatile 变量的修改对其他线程立即可见。
  • 有序性:禁止编译器和处理器对 volatile 变量的读写操作进行重排序。

2. 可见性的实现

(1) 内存屏障的插入

JVM 会在 volatile 变量的读写操作前后插入内存屏障,强制线程遵守以下规则:

  • 写操作(Write)

    1. StoreStore 屏障:确保 volatile 写之前的普通写操作不会被重排序到 volatile 写之后。
    2. StoreLoad 屏障:确保 volatile 写之后的操作不会被重排序到 volatile 写之前。
    volatile int x = 1;
    x = 2; // 写操作
    // JVM 插入 StoreStore + StoreLoad 屏障
    
  • 读操作(Read)

    1. LoadLoad 屏障:确保 volatile 读之后的操作不会被重排序到 volatile 读之前。
    2. LoadStore 屏障:确保 volatile 读之后的普通写操作不会被重排序到 volatile 读之前。
    int y = x; // 读操作
    // JVM 插入 LoadLoad + LoadStore 屏障
    
(2) 强制刷新主内存
  • 写操作:线程修改 volatile 变量后,立即将工作内存(CPU 缓存)中的值刷新到主内存。
  • 读操作:线程每次读取 volatile 变量时,直接从主内存加载最新值,而非本地缓存。

3. 有序性的实现

通过内存屏障禁止指令重排序,具体规则如下:

  • 禁止重排序场景
    • volatile 写之前的操作不能重排序到写之后。
    • volatile 读之后的操作不能重排序到读之前。
    • volatile 写与后续的 volatile 读/写不能重排序。
示例:双重检查锁定(DCL)
public class Singleton {private static volatile Singleton instance;public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton(); // 1.分配内存 2.初始化对象 3.赋值引用}}}return instance;}
}
  • volatile 时的风险:步骤2和3可能被重排序,导致其他线程获取未初始化的对象。
  • volatile 的作用:禁止步骤3(赋值引用)重排序到步骤2(初始化对象)之前。

4. 底层硬件支持

(1) 缓存一致性协议(如 MESI)
  • MESI 协议:CPU 通过监听总线(Bus Snooping)维护缓存一致性。
    • 当某个 CPU 核心修改了缓存中的 volatile 变量,会触发缓存行的 失效(Invalidate) 操作,强制其他核心的缓存失效并从主内存重新加载。
(2) 内存屏障的硬件实现
  • x86 架构
    • StoreStore 屏障:通常为空操作(x86 强内存模型保证普通写不会重排序到 volatile 写之后)。
    • StoreLoad 屏障:通过 mfence 指令或 lock 前缀实现。
  • ARM 架构:通过 DMB(Data Memory Barrier)指令显式插入屏障。

5. volatile 与锁的对比

特性volatile锁(synchronized/Lock)
原子性不保证(如 i++ 需额外同步)保证(互斥执行代码块)
可见性保证(通过内存屏障)保证(锁释放时刷新内存)
有序性限制部分重排序限制所有临界区内的重排序
适用场景单写多读、状态标志复合操作、临界区资源保护
性能开销低(无上下文切换)高(上下文切换、阻塞)

6. 实际应用场景

  1. 状态标志

    volatile boolean isRunning = true;
    public void stop() { isRunning = false; }
    public void run() { while (isRunning) { /* 任务循环 */ } }
    
  2. 单例模式(DCL)
    如前文示例,volatile 防止对象初始化时的指令重排序。

  3. 发布不可变对象

    volatile Config config;
    // 线程1初始化配置
    config = new Config(...); // 安全发布
    // 线程2读取配置(保证看到完整初始化的对象)
    

总结

volatile 的底层实现依赖 JVM 内存屏障硬件缓存一致性协议

  1. 内存屏障:强制线程遵守读写顺序,刷新或加载主内存数据。
  2. 缓存一致性协议:确保多核 CPU 的缓存状态一致。
    volatile 适用于单写多读场景,能高效解决可见性和有序性问题,但无法替代锁的原子性保障。正确使用需结合具体业务场景,避免误用导致线程安全问题。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/82800.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/82800.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/82800.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《零基础学机器学习》学习大纲

《零基础学机器学习》学习大纲 《零基础学机器学习》采用对话体的形式,通过人物对话和故事讲解机器学习知识,使内容生动有趣、通俗易懂,降低了学习门槛,豆瓣高分9.1分,作者权威。 接下来的数篇文章,我将用…

C# 中 static的使用

静态(static)是C#中一个重要的关键字,它可以应用于类、方法、属性和字段。 静态类 静态类的特点: 不能实例化只能包含静态成员密封的(sealed),不能被继承 应用场景: 工具类/辅助类数学计算类:如Math类…

C++蓝桥杯真题(题目+解析+流程图)(特殊运算符+四叶玫瑰数+质因数的个数+最大的矩形纸片+数字游戏+活动人数)

C++蓝桥杯真题 蓝桥杯省赛C++题目分析1. 特殊运算符题目描述输入描述输出描述输入输出样例正确代码错误代码分析流程图2. 四叶玫瑰数题目描述输入描述输出描述输入输出样例正确代码错误代码分析流程图3. 质因数的个数题目描述输入描述输出描述输入输出样例正确代码错误代码分析…

MYSQL 索引与数据结构笔记

MYSQL 索引与数据结构笔记 文章目录 MYSQL 索引与数据结构笔记1. B-Tree 与 B Tree 基础对比一、B 树的优势二、B 树的进一步优化三、综合对比结论 2. MySQL 为何选择 B Tree3. 索引使用示例与性能分析3.1 整数字段索引查询3.2 字符字段索引查询 4. 索引失效与类型转换陷阱5. 小…

电路中的DGND、GROUND、GROUND_REF的区别,VREF、VCC、VDD、VEE和VSS的区别?

目录 1 DGND、GROUND、GROUND_REF的区别 1.1 DGND(Digital Ground) 1.2 GROUND(Ground) 1.3 GROUND_REF(Ground Reference) 1.4 区别 2 VREF、VCC、VDD、VEE和VSS的区别 2.1 VREF(Refere…

OpenHarmony平台驱动开发(十),MMC

OpenHarmony平台驱动开发(十) MMC 概述 功能简介 MMC(MultiMedia Card)即多媒体卡,是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 MMC后续泛指一个接口协定(一种卡式)&#xff0…

C++ 的 VS 项目中引入跨平台包管理工具 conan

我们知道 C 不像很多其他语言有包管理工具,比如 Python 有 pip,Java 有 maven,C# 有 nuget,JS 有 npm,Go 有 go mod,Rust 有 cargo,项目中需要自己手动引入第三方库,手动维护带来了很…

vscode 默认环境路径

1.下面放在项目根目录上: .vscode/settings.json 2.settings.json内容: {"python.analysis.extraPaths": ["${workspaceFolder}"],"python.defaultInterpreterPath": "/shared_disk/users/lbg/envs/py310_see3d/b…

Android 项目中配置了多个 maven 仓库,但依赖还是下载失败,除了使用代理,还有其他方法吗?

文章目录 前言解决方案gradlemaven 仓库 前言 我们在Android 开发的过程中,经常会遇到三方依赖下载不下来的问题。一般情况下我们会在项目的build.gradle文件中配置多个 maven 仓库来解决。 // Top-level build file where you can add configuration options com…

uni-app 引入vconsole web端正常,安卓端报错 Cannot read property ‘sendBeacon‘ of undefined

reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property sendBeacon of undefined vconsole 只支持 web 端,…

火山RTC 7 获得远端裸数据

一、获得远端裸数据 1、获得h264数据 1&#xff09;、远端编码后视频数据监测器 /*** locale zh* type callback* region 视频管理* brief 远端编码后视频数据监测器<br>* 注意&#xff1a;回调函数是在 SDK 内部线程&#xff08;非 UI 线程&#xff09;同步抛出来的&a…

web 自动化之 Unittest 四大组件

文章目录 一、如何开展自动化测试1、项目需求分析&#xff0c;了解业务需求 web 功能纳入自动化测试2、选择何种方式实现自动化测试 二、Unittest 框架三、TestCase 测试用例四、TestFixture 测试夹具 执行测试用例前的前置操作及后置操作五、TestSuite 测试套件 & TestLoa…

42、在.NET 中能够将⾮静态的⽅法覆写成静态⽅法吗?

在.NET中&#xff0c;不能将非静态方法&#xff08;实例方法&#xff09;直接覆写&#xff08;Override&#xff09;为静态方法&#xff08;Static Method&#xff09;。以下是关键原因和解释&#xff1a; 1. 方法绑定的本质区别 实例方法&#xff1a;属于对象的实例&#xf…

8天Python从入门到精通【itheima】-1~5

目录 1节&#xff1a; 1.Python的优势&#xff1a; 2.Python的独具优势的特点&#xff1a; 2节-初识Python&#xff1a; 1.Python的起源 2.Python广泛的适用面&#xff1a; 3节-什么是编程语言&#xff1a; 1.编程语言的作用&#xff1a; 2.编程语言的好处&#xff1a;…

3D迷宫探险:伪3D渲染与运动控制的数学重构

目录 3D迷宫探险:伪3D渲染与运动控制的数学重构引言第一章 伪3D渲染引擎1.1 射线投射原理1.2 纹理透视校正第二章 迷宫生成算法2.1 图论生成模型2.2 复杂度控制第三章 第一人称控制3.1 运动微分方程3.2 鼠标视角控制第四章 碰撞检测优化4.1 层级检测体系4.2 滑动响应算法第五章…

mac一键安装gpt-sovit教程中,homebrew卡住不动的问题

mac一键安装gpt-sovit教程 仅作为安装过程中解决homebrew卡住问题的记录 资源地址 https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/znoph9dtetg437xb#mlAoP 下载一键包 下载后并解压&#xff0c;找到install for mac.sh&#xff0c;终端执行bash空格拖拽in…

git 远程仓库管理详解

Git 的远程仓库管理是多人协作和代码共享的核心功能。以下是 Git 远程仓库管理的详细说明&#xff0c;包括常用操作、命令和最佳实践。 1. 什么是远程仓库&#xff1f; 远程仓库&#xff08;Remote Repository&#xff09;&#xff1a;存储在网络服务器上的 Git 仓库&#xff0…

【超详细教程】安卓模拟器如何添加本地文件?音乐/照片/视频一键导入!

作为一名安卓开发者或手游爱好者&#xff0c;安卓模拟器是我们日常工作和娱乐的重要工具。但很多新手在使用过程中常常遇到一个共同问题&#xff1a;**如何将电脑本地的音乐、照片、视频等文件导入到安卓模拟器中&#xff1f;**今天&#xff0c;我将为大家带来一份全网最详细的…

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json&#xff0c;修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖&#xff0c;注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

uniapp|实现手机通讯录、首字母快捷导航功能、多端兼容(H5、微信小程序、APP)

基于uniapp实现带首字母快捷导航的通讯录功能,通过拼音转换库实现汉字姓名首字母提取与分类,结合uniapp的scroll-view组件与pageScrollTo API完成滚动定位交互,并引入uni-indexed-list插件优化索引栏性能。 目录 核心功能实现动态索引栏生成​联系人列表渲染​滚动定位联动性…