【多线程】volatile关键字

这篇具有很好参考价值的文章主要介绍了【多线程】volatile关键字。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、volatile
  • 1.volatile的底层原理是内存屏障,Memory Barrier, Memory Fence
  • 2.对volatile变量的写指令(赋值操作)后会加入写屏障
  • 3.对volatile变量的读指令(取变量值)前会加入读屏障
  • 4.写屏障的作用会将写屏障之前的赋值改动操作,对共享变量的改动都同步到主内存中
  • 5.读屏障的作用会将读屏障之后的对共享变量的读取,加载的是主存中最新的数据
  • 6.写屏障的作用会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
  • 7.读屏障的作用会确保指令重排序时,不会将读屏障之后的代码排在读屏障之前
  • 8.不能解决指令交错,写屏障仅仅是保证之后的读能够读到最新的结果,不能保证另个线程b在线程a写之前读,然后在线程a写之后,线程b再写
  • 9.有序性的保证只保证了本线程内相关代码不被重新排序
  • 10.jdk1.5之后才能生效
二、保证可见性
  • 1.写屏障(sfence)保证在该屏障之前的,对共享变量的改动,都同步到主存之中
  • 2.volatile a变量,当a变量被赋值后,a=1后会加入一个写屏障,会将a=1赋值操作之前的对共享变量的改动都同步到主存中
  • 3.读屏障(lfence)保证在该屏障之后,对共享变量的读取,加载的是主存中最新数据
  • 4.volatile a变量,当if(a==2)时,读取a变量前会加一个读屏障,在读屏障之后对共享变量的读取加载的都是主存中最新的数据
三、保证有序性
  • 1.写屏障会确保指令重排时,不会将写屏障之前的代码排在写屏障之后,例如int a = 2;boolean b = true; 假如b是被volatile关键字修饰,则给b赋值为true之后,会产生一个写屏障,那么写屏障之前的操作 a=2的赋值操作不会重排到写屏障之后,也就是保证了a=2赋值操作在b=true的赋值操作之前
  • 2.读屏障会确保指令重排时,不会将读屏障之后的代码排在读屏障之前,例如if(b); int a = 2; 假如b是被volatile关键字修饰,则读取b变量时,会给b变量读操作前加一个读屏障,在读屏障之后的代码a=2,不会重排在读屏障之前,因此保证a=2操作在if(b)读b变量之后
四、不能解决指令交错
  • 1.线程a和线程b,修改volatile关键字修饰的变量i
  • 2.线程a对变量i进行自加1操作,线程b对变量i进行自减1操作
  • 3.开始线程a读取变量i为0,线程b读取变量i为0
  • 4.线程a自加1成功,并将i=1写回主存,线程b自减成功,并将i=-1写回主存
  • 5.此时主存中变量i的值为-1,正常来说结果应该是0
  • 6.且在线程a、b各自的线程内,都能保证各自的指令有序,不能重排序
  • 7.因此volatile关键字修饰的变量没有解决指令交错带来的线程安全问题
  • 8.线程a、线程b之间的指令会有一定的交错,volatile不能保证原子性
  • 9.synchronized可以保证可见性、有序性和原子性(共享变量要完全在synchronized代码块内,如果代码块外部还有变量的使用,则不能保证指令不重排)

文章来源地址https://www.toymoban.com/news/detail-462703.html

到了这里,关于【多线程】volatile关键字的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JavaEE初阶】多线程(三)volatile wait notify关键字 单例模式

    摄影分享~~ 以上代码运行的结果可能是输入1后,t1这个线程并没有结束。而是一直在while中循环。而t2线程已经执行完了。 以上情况,就叫做 内存可见性问题 这里使用汇编来理解,大概分为两步操作: load,把内存中flag的值,读到寄存器中。 cmp,把寄存器中的值,和0进行比

    2023年04月25日
    浏览(42)
  • 【iOS】—— 属性关键字及weak关键字底层原理

    参考博客:IOS开发基础——属性(copy strong weak等) 内存管理有关的: weak , assign , strong , retain , copy 线程安全有关的的: nonatomic , atomic 访问权限有关的的: readonly , readwrite (只读,可读写) 修饰变量的: const , static , extern 这些

    2024年02月16日
    浏览(42)
  • volatile 关键字详解

    目录 volatile volatile 关键用在什么场景下: volatile 防止编译器优化: volatile   是一个在许多编程语言中(包括C和C++)用作的标识符。它用于告诉编译器不要对带有该修饰的变量进行优化,以确保变量在特定情况下的可见性和预测性。 在C和C++中, volatile

    2024年02月11日
    浏览(43)
  • volatile关键字作用

    volatile是一个和多线程相关的,主要有一下2点作用(只保证可见性,不保证原子性) 防止指令重排(有序性) JVM在不改变程序执行结果的前提下,在编译时会对指令的顺序进行重新排序,而volatile则能够禁止指令的重新排序 能够确保线程内存中的对象对其他内存可

    2024年02月15日
    浏览(46)
  • JAVA volatile 关键字

    volatile 是JAVA虚拟机提供的轻量级的同步机制,有三大特性 1、保证可见性  2、不保证原子性  3、禁止指令重排 JMM  JAVA内存模型本身是一种抽象的概念并不真实存在 它描述的是一组规则或规范,提供这组规范定义了程序中各个变量(包括实例变量、静态变量)的访问方式。

    2024年02月13日
    浏览(52)
  • [JAVAee]volatile关键字

    目录 1.volatile的特性 ①保持线程可见性 2.volatile注意事项及适用场景 ①注意事项 ②适用场景 volatile,译为\\\"易变的\\\". 对此我们就可以这样理解,对于被volatile修饰的变量的数值,是容易变化的. 在之前的线程安全文章中,我们有讲解过\\\"可见性\\\",对于线程间的这个特性可能会导致:线程

    2024年02月16日
    浏览(36)
  • 【C】volatile 关键字

    1)基本概念 const 是C语言的一个。 const 用于告诉编译器相应的变量可能会在程序的控制之外被修改,因此编译器不应该对其进行优化。 声明语法: 作用: 防止编译器优化,确保对变量的每次访问都是实际的读写操作,而不是使用缓存中的值。 用于表示可能会 被异步

    2024年01月22日
    浏览(42)
  • 【Java基础】volatile关键字

    关于作者:CSDN内容合伙人、技术专家, 从零开始做过日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 我们继续总结学习Java基础知识,温故知新。 volatile 是一个Java,可以用来修饰变量,volatile也被称为轻

    2024年02月11日
    浏览(46)
  • C语言volatile关键字

    在C语言中, volatile 是一个类型修饰符,用于告诉编译器对象的值可能会在编译器无法检测到的情况下被改变。这通常发生在以下两种情况: 硬件的输入/输出操作,例如一个设备寄存器的读取或写入。 共享内存的并行程序,其中一个线程修改了一个内存位置,而另一个线程

    2024年02月07日
    浏览(54)
  • 浅析Java中volatile关键字

            Java中的volatile用于修饰一个变量,当这个变量被多个线程共享时,这个变量的值如果发生更新,每个线程都能获取到最新的值。volatile在多线程环境下还会禁止指令重排序,确保变量的赋值操作按照代码的顺序执行。需要注意是它不能保证变量操作的

    2024年01月21日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包