热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

并发编程深度解析(六):volatile关键字详解——as-if-serial指令重排序与内存模型分析

在并发编程中,`as-if-serial`原则确保了即使编译器和处理器对指令进行重排序,单线程的执行结果也不会受到影响。这一原则要求编译器、运行时环境和处理器必须严格遵守,以保证程序的正确性。本文深入探讨了`volatile`关键字的内存模型,详细分析了其在多线程环境中的可见性和有序性特性,以及如何通过`as-if-serial`规则来确保数据的一致性和可靠性。

as-if-serial

不管编译器和处理器怎么重排序,单线程的执行结果都不能被改变。编译器,运行时和处理器都必须遵守as-if-serial

可见性实现原理

volatile 变量的内存可见性是基于内存屏障(Memory Barrier)实现。.

  1. 内存屏障,又称内存栅栏,是一个 CPU 指令。
  2. 在程序运行时,为了提高执行性能,编译器和处理器会对指令进行重排序,JMM 为了保证在不同的编译器和 CPU 上有相同的结果,通过插入特定类型的内存屏障来禁止特定类型的编译器重排序和处理器重排序,插入一条内存屏障会告诉编译器和 CPU:不管什么指令都不能和这条 Memory Barrier 指令重排序。
  • 被volatile修饰编译后,会产生一个LOCK#前缀来对总线加锁其他CPU对内存读写阻塞(总线加锁方式)直到锁释放
  • 后通过缓存一致性协议和嗅探技术来解决的;

请参照上篇文章:并发编程系列(五)volatile关键字详解(1)

禁止指令重排的原理分析

被volatile 修饰的变量禁止指令重排,那这个关键字是如何禁止指令重排序的呢?

在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序:

编译器优化重排序:编译器在不改变单线程语义的前提下,可以安排语句的执行顺序

指令级并行的重排序:现代处理器采用了指令级并行技术(INnstruction-Level Parallelism,ILP),如果不存在数据依赖性,处理器可以改变语句对应的机器指令的执行顺序

内存系统的重排序:由于处理器使用缓存和读 / 写缓冲区,这使得加载和储存操作看上去可能是在乱序执行

对于编译器,JMM的编译器重排序规则会禁止特定类型的编译器重排序,【不是所有的编译器重排序都要禁止】

对于处理器重排序,JMM的处理器重排序规则会要求java编译器生成指令时插入特定类型的内存屏障【memory barriers】指令。通过内存屏障指令来禁止特定类型的处理器重排序,为程序员提供一致的内存可见性保证

JVM规范了视图定义一种JMM来屏蔽各个硬件平台和OS的内存访问差异,属于语言级的内存模型,实现让Java程序在各平台下都能达到一致的内存访问效果,通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证。

内存屏障

为了实现volatile可见性和happen-before的语义,JVM底层通过一个叫做“内存屏障”的东西来完成。内存屏障,也叫做内存栅栏,是一组处理器指令,用于实现对内存的顺序限制,

是否可以重排序 第二个操作
第一个操作 普通读 / 写  volatile volatile写
普通读 / 写      
volatile读 no no no
volatile写   no no

当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后。

当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前。

当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。对于编译器来说,发现一个最优布置来最小化插入屏障的总数几乎不可能。为此,JMM采取保守策略。下面是基于保守策略的JMM内存屏障插入策略。

JMM:JMM属于语言级的内存模型,它确保在不同的编译器和不同的处理器平台上,通过禁止特定类型的编译器重排序和处理器冲排序,为程序员提供了一致的内存可见性保证

 

并发编程系列(六)volatile 之 as-if-serial 指令重排 volatile内存语义 volatile原理

 

volatile写和volatile读的内存屏障插入策略非常保守。在实际执行时,只要不改变volatile写-读的内存语义,编译器可以根据具体情况忽略不必要的屏障。在JMM基础中就有提到过各个处理器对各个屏障的支持度,其中x86处理器仅会对写-读操作做重排序。

原理

volatile主要作用是具有可见性和原子性(单个变量),其实现原理就是利用屏障来保障实现。

要想彻底掌握就应该多做下相关场景的编码,经典的场景有:状态标记量、volatile方式的double check等。单例的双重检查


推荐阅读
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 优化ASM字节码操作:简化类转换与移除冗余指令
    本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 理解存储器的层次结构有助于程序员优化程序性能,通过合理安排数据在不同层级的存储位置,提升CPU的数据访问速度。本文详细探讨了静态随机访问存储器(SRAM)和动态随机访问存储器(DRAM)的工作原理及其应用场景,并介绍了存储器模块中的数据存取过程及局部性原理。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文深入探讨了C++对象模型中的一些细节问题,特别是虚拟继承和析构函数的处理。通过具体代码示例和详细分析,揭示了书中某些观点的不足之处,并提供了更合理的解释。 ... [详细]
author-avatar
手机用户2502921877
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有