voliate关键字原理

voliate关键字原理被volatile修饰的变量在编译成字节码文件时会多个lock指令,该指令在执行过程中会生成相应的内存屏障,以此来解决可见性跟重排序的问题。voliate关键字作用静止重排序保证变量赋值操作的顺序与程序代码中的执行顺序一致。线程可见性原理使用场景…

大家好,又见面了,我是你们的朋友全栈君。

被volatile修饰的变量在编译成字节码文件时会多个lock指令,该指令在执行过程中会生成相应的内存屏障,以此来解决可见性跟重排序的问题。

预备知识
  • 指令重排序
    • 为什么到指令重排序:一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
    • 指令重排序遵守的准则:编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。
    • 什么办法来禁止指令重排序呢:添加内存屏障
  • 内存屏障
    • 内存屏障分类:内存屏障分为两种:Load Barrier 和 Store Barrier即读屏障和写屏障。
    • 内存屏障作用:
      (1)阻止屏障两侧的指令重排序,即屏障下面的代码不能和屏障上面的代码交换顺序(静止重排序)
      (2)在有内存屏障的地方,线程修改完共享变量以后会马上把该变量从本地内存写回到主内存,并且让其他线程本地内存中该变量副本失效(使用MESI协议)(线程可见性)
      对于Load Barrier来说,在指令前插入Load Barrier,可以让高速缓存中的数据失效,强制从新从主内存加载数据;
      对于Store Barrier来说,在指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,其他线程程可见
voliate关键字作用
  • 静止重排序: voliate修饰的变量,保证变量赋值操作的顺序与程序代码中的执行顺序一致

  • 线程可见性: 当一条线程修改了voliate变量的值,新值对于其他线程来说是可以立即得知的

原理
  • volatile关键字修饰的变量会存在一个“lock:”的前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线或高速缓存加锁(一般只是对缓存行枷锁),可以理解为CPU指令级的一种锁。
  • 在具体的执行上,它先对总线或缓存加锁,然后执行后面的指令,在Lock锁住总线的时候,其他CPU的读写请求都会被阻塞,直到锁释放。最后释放锁后会把高速缓存中的脏数据(修改过的数据)全部刷新回主内存,且这个写回内存的操作会使在其他CPU里缓存了该地址的数据无效。
  • 在java内存层面可以理解为:当需要使用(use)这个变量时,必须从主存中read–>load这个变量(即要使用这个变量时,必须从主存中读取这个变量,这就保证了该变量是最新的);当线程工作内存中这个变量被赋值时(assign),那么立刻store–>write这个变量(即当该值计算完成,立刻把这个变量写会主存,并且使得该值在其他内存的工作变量中无效)
java内存屏障

在这里插入图片描述

volatile语义中的内存屏障

volatile的内存屏障策略非常严格保守,非常悲观且毫无安全感的心态:

  • 在每个volatile写操作前插入StoreStore屏障(这个屏障前后的2个Store指令不能交换顺序),在写操作后插入StoreLoad屏障(这个屏障前后的2个Store Load指令不能交换顺序);
  • 在每个volatile读操作前插入LoadLoad屏障(这个屏障前后的2个Load指令不能交换顺序),在读操作后插入LoadStore屏障(这个屏障前后的2个Load Store指令不能交换顺序);

由于内存屏障的作用,避免了volatile变量和其它指令重排序、线程之间实现了通信,使得volatile表现出了锁的特性。
在Java中对于volatile修饰的变量,编译器在生成字节码时,会在指令序列中插入内存屏障禁止处理器重排序。

举例

两条线程Thread-A与Threab-B同时操作主存中的一个volatile变量i时。Thread-A写了变量i,那么:
Thread-A发出LOCK#指令
(1)发出的LOCK#指令锁总线(或锁缓存行)(因为它会锁住总线,导致其他CPU不能访问总线,不能访问总线就意味着不能访问系统内存),然后释放锁,最后刷新回主内(瞬间完成的,写回时候其他缓存行失效),同时让Thread-B高速缓存中的缓存行内容失效。
(2)Thread-A向主存回写最新修改的i
Thread-B读取变量i,那么:
Thread-B发现对应地址的缓存行被锁了,等待锁的释放,缓存一致性协议会保证它读取到最新的值(重新从主存读)
由此可以看出,volatile关键字的读和普通变量的读取相比基本没差别,差别主要还是在变量的写操作上。

举例

在这里插入图片描述

使用场景

满足以下两点,那么volatile修饰的共享变量,不用加锁也能保证线程安全:

  • 运算结果不依赖变量的当前值(即变量计算的结果和当前的值没有关系,比如一个boolean变量的改变,但是i++这种运算就存在依赖关系,以为新值是在旧值的基础上加1),或者能够确保只有单一的线程修改变量的值
  • 变量不需要与其他的状态变量共同参与不变性约束(即该变量不和其他变量关联)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134267.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • WiFi 2.4G和5G信道分布说明(认证相关)

    WiFi 2.4G和5G信道分布说明(认证相关)FCC36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165IC 36,40,44,48,52,56,60,64,149,153,157,161ETSI 36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140SPAIN 36,40,44,48,52,56,60,64,100,104,108,112,116,120,124.

  • Vue + Spring Boot 项目实战(一):项目简介

    Vue + Spring Boot 项目实战(一):项目简介白卷是一款使用Vue+SpringBoot开发的前后端分离项目,主要帮助web开发初学者通过实践方式打通各个环节的知识。

  • 类UNIX操作系统概念

    摘要:对unixos上的一些基本概念做一个统一的梳理,以下内容转自互联网和相关书籍一进程组、会话、控制终端进程组进程组是一个或多个进程的集合。每个进程组有一个称为组长的进程,组长进程就是其进

    2021年12月25日
  • 磁盘管理器能看到u盘,但电脑里没有_bt3安装到u盘启动不了

    磁盘管理器能看到u盘,但电脑里没有_bt3安装到u盘启动不了最近在弄bt3U盘版的时候,依照网上的方法弄了半天都有问题,一直都进不去xwindow,由于spoonwep工具是有界面的,故只在命令行下如果没有界面的支持,是不能办事的,后来在网上看到很多兄弟们说显卡的问题,结果在无线网论坛里找到了ATI卡的驱动,具体下载的地址是:http://www.wlanbbs.com/thread-5439-1-1.html  非常感谢这位提供驱动的兄弟,ATI在哪

  • Struts2 FilterDispatcher的作用[通俗易懂]

    Struts2 FilterDispatcher的作用[通俗易懂]org.apache.struts2.dispatcher.FilterDispatcher是Struts2的主要的Filter,负责四个方面的功能:  (1)执行Actions  (2)清除ActionContext  (3)维护静态内容  (4)清除request生命周期内的XWork的interceptors  另注:该过滤器应该过滤所有的请求URL。一般被设置

  • 智能视频识别技术的发展现状「建议收藏」

    智能视频识别技术的发展现状「建议收藏」一、智能视频分析技术应用现状  作为强化视频监控系统应用的一门主要技术——视频智能分析技术,近几年一直得到业界的广泛的关注,其通过对视频内容的分析,将客户所关注的目标从监控背景中分离出来,按照目标的移动方向、速度、时间等参数和某些行为特征进行关联,从而达到主动监控防御的目的。按说这一技术的大规模推广应用对于提高当前治安监控系统的利用效率将起到很大的作用,但实际上却没有得到有效的推广,所谓“叫好不叫座”。笔者认为,造成这一现象的主要原因有以下几个方面:【您可以是大型系统集成商、可以是相关贸易的经销商.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号