voliate关键字的应用误区

voliate关键字的应用误区写下这篇博客也是因为本人之前对voliate关键字理解不透彻,才有了应用误区,希望同样没有理解到位的朋友可以一起踩坑,也欢迎上帝视角明明白白的大佬指出本文的不当之处。先说一下自己之前对voliate的理解,voliate通过内存屏障可以禁止指令重排序和保证可见性,但是不能保证并发安全。禁止指令重排序就不说了,主要说一说如何保证可见性以及为什么不能保证并发安全。首先理解一下一个线程如何去修改…

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

写下这篇博客也是因为本人之前对voliate关键字理解不透彻,才有了应用误区,希望同样没有理解到位的朋友可以一起踩坑,也欢迎上帝视角明明白白的大佬指出本文的不当之处。

先说一下自己之前对voliate的理解,voliate通过内存屏障可以禁止指令重排序和保证可见性,但是不能保证并发安全。禁止指令重排序就不说了,主要说一说如何保证可见性以及为什么不能保证并发安全。

首先理解一下一个线程如何去修改变量a的值,有三步:

第一步从主内存中读取a的值到该线程的工作内存。

第二步在工作内存中修改a。

第三步将a的值刷回主内存。

被voliate修饰的变量在进行写操作时,处理器会多一条Lock指令,Lock指令会将修改后的值直接写进主内存。同时还会让其他线程的工作内存中缓存的a的值失效,这两点就可以保证了可见性,我理解的可见性是指所有线程修改a之前a的值都和主内存中一样,都是一致的。

举个栗子如果有两个thread同时操作voliate修饰变量a,thread1和thread2都将a的值从主内存中读取到工作内存中之后,thread2对a做了修改之后会使thread1工作内存中a的值失效,同时及时地将a的值刷新进主内存,这时候thread1想去修改a发现自己工作内存中的值失效了,就会去主内存中重新读取,这样就避免了典型的并发问题。日常voliate的应用场景中喜欢用来修饰全局变量,曾经以为这样就可以避免该全局变量并发问题,其实不是的。

因为voliate不能将一个非原子性的操作变为原子性。所谓原子性的操作是指该操作在执行期间不受其他操作影响。上面这个对例子中对变量a的值做修改这就不是一个原子性操作,因为这个操作有三步。

还是刚刚那个例子加深一下理解。thread1如果在第一步和第二步中间a的值被thread2修改了,这时候thread1应该在thread2修改之后的a的基础上再做修改,总之thread1的操作结果就要受其他线程影响了。重点来了!voliate可以保证thread1的操作结果正确,但是它不能阻止thread2去影响thread1的操作结果。这就是voliate不能将一个非原子性的操作变为原子性,但是加锁(该变量只能同时被一个线程操作)或者CAS无锁可以,这是题外话。

说了这么多还是没有说为什么voliate不能保证并发安全。先看个情景,还是上面这个例子,刚说thread1在第一步和第二步之间的时候thread2把a修改了,这时候voliate棒棒的一系列骚操作让thread1在执行第二步真正去修改a的时候拿到的还是最新的即thread2修改之后刷新回主内存的值。但是如果thread1在第二步和第三步之间的时候thread2把a修改了呢!这时候thread1已经把a修改完了,已经准备刷回主内存了,这里大家不要和我一样钻牛角尖,之前我也在想,thread2把a修改了刷回主内存那thread1工作内存里a的值不就失效了?thread1已经修改完了就不会再去主内存中读a的值再修改一遍了,它现在要做的是把刚刚修改好a的值也刷回主内存,哦吼,这样一刷就出问题了。这就是voliate不能保证原子性也就是为什么不能保证并发安全的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143940.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 各种聚类算法的介绍和比较「建议收藏」

    一、简要介绍1、聚类概念聚类就是按照某个特定标准(如距离准则)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。2、聚类和分类的区别聚类技术通常又被称为无监督学习,因为与监督学习不同,在聚类中那些表示数据类别的分类或者分组信息是没有的。Clustering(聚类),

    2022年4月16日
    79
  • HTTP和HTTPS的区别,有什么优缺点「建议收藏」

    HTTP和HTTPS的区别,有什么优缺点「建议收藏」http和https:http就是超文本传输协议的缩写,用于从网站服务器传输数据到上网者的本地浏览器的协议https就是在http的基础加上了SSL或者其他的加密方式,所以这就是最主要的区别。原因:因为http在传输的时候是以明文的方式传输数据,这样的话在传输过程中如果被截获就能直接读取信息,所以并不安全,因此需要通过某种方式加密。怎样解决http不安全的问题呢?解决方法就是在http的基础上加上了SSL协议SSL,安全套接字协议,他是靠证书来验证服务端的身份,并在本地

    2022年8月31日
    5
  • 5线上模式刷2亿bug_GTA5还想冲销量?玩家利用BUG刷钱,遭受比封号更严厉惩罚

    5线上模式刷2亿bug_GTA5还想冲销量?玩家利用BUG刷钱,遭受比封号更严厉惩罚  《GTA5》作为一款神级开放世界游戏,即便已经发售了七年,凭借其优秀的品质以及耐玩性,而今仍旧是许多玩家讨论的焦点。不过在近期,鲜有出现负面消息的R星却因为线上模式的BUG而受到了玩家们的非议。  《GTA5》说是游戏,但你在玩的过程中不自觉就代入到了主角的视角中。跟现实世界一样,美金在游戏中也非常重要。有了钱,你就可以在洛圣都这个虚拟世界中过自己想要的生活。  但玩家在游戏中无论是使用合法的…

    2022年4月26日
    347
  • Mac的pycharm中快捷键command+a不能全选「建议收藏」

    Mac的pycharm中快捷键command+a不能全选「建议收藏」问题:今天在pycharm中想使用快捷键全选结果:command+a的时候不是全选而是showusages原因:是因为安装了ideavim插件解决方法:卸载掉ideavim插件找到这个插件ideavim卸载uninstall卸载之后提示重启,重启就ok了。…

    2022年5月9日
    134
  • awk基本用法简介

    awk基本用法简介之前说过sed,今天来说awk,它也是一个文本处理器,是linux下的一个命令,比sed更强大。搞linux开发,尤其是后台开发,这个命令几乎必须要用到。awk这三个字母分别代表其三位作者的名字,而不是某个/某些有意义单词的缩写。还是那句话,以实践操作为荣,以只看不练为耻。当然,理解awk的原理是必须的:读入有’\n’换行符分割的一条记录,将记录按指定的域分隔符划分域,$0表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是空格键或tab键。

    2022年7月11日
    14
  • navicat 15 mac激活码[最新免费获取]

    (navicat 15 mac激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~CIOU…

    2022年3月26日
    59

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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