java volatile 原子性_Java中volatile不能保证原子性的证明

Java并发编程之验证volatile不能保证原子性

通过系列文章的学习,凯哥已经介绍了volatile的三大特性。1:保证可见性 2:不保证原子性 3:保证顺序。那么怎么来验证可见性呢?本文凯哥(凯哥Java:kaigejava)将通过代码演示来证明为什么说volatile不能够保证共享变量的原子性操作。

我们来举个现实生活中的例子:

中午去食堂打饭,假设你非常非常的饥饿,需要一荤两素再加一份米饭。如果食堂打饭的阿姨再给你打一个菜的时候,被其他人打断了,给其他人打饭,然后再回过头给你打饭。你选一荤两素再加一份米饭打完的过程被打断了四次耗时30分钟。你想想你自己的感受。是不是要疯了,要暴走了!其实,如果把从你点菜到阿姨给你打完饭这个过程,看着计算机的一个线程执行过程的话,那么在你点菜到你拿到饭菜这个过程是一个完整的,不能被打断的,这就是所谓的原子性。如果被多次打断的话想想你的心理,就知道程序如果在执行过程被打断后的结果了。

原子性操作的定义:

所谓的原子性操作就是线程对变量的操作一旦开始,就会一直运行直到结束。中介不会因为其他原因而切换到另一个线程。操作是不可分割的,在执行完毕之前是不会被其他任务或是事件中断的。一个操作或者是多个操作要么执行都成功要么执行都失败(可以结合数据库的原子性理解)。

怎么证明volatile修饰的共享变量就不能保证原子性呢?

模拟场景:

共享变量volatile int number=0;执行number++操作。使用多个线程多次调用。看看使用volatile修饰的number在执行结束后的结果是否是我们预期的结果。

我们分别用10个线程执行100次,50个线程执行1000次以及50个线程执行一百万次来看看结果。

先来看看变量是用volatil修饰的

33dbbf4b1e5533b9ed019705bd5fc57a.png

再来看看主线程里面:

af22015f1728e71b5aa21061d439197c.png

按照上面咱们规定的线程数量运行次数来看看咱们预期结果和实际运行结果:

我们分别用10个线程执行100次,50个线程执行1000次以及50个线程执行一百万次来

8b89d5f3ce728e39a825db1c9bcf5ce9.png

320f2d931c6fdce23de3d4ccf3084c02.png

从上面表格中我们可以看到,即时共享变量用volatile修饰了。但是随着线程数量或者执行次数的增加,实际运行结果与预期结果相差越来越大。如果预期结果和运行结果一致则说明保证了原子性,但是从结果来看不是这样的。从而证明了volatile的第二个特性:不能保证原子性。

为什么从i++的运行结果上就能看出不保证原子性呢?

我们来分析:

正常来说200个线程,每个线程执行了1000次。最后应该输出的是:200*1000=20000.二十万。但是实际结果却不是二十万次。那说明了什么呢?请看下图:

2cf8f625b0502b69e42b399d06e1b95f.png

说明:

主内存中有共享变量number的值是0,现在有4个CPU带着4个线程都从主内存中copy变量到自己的工作区。这个是CPU1先竞争到然后再线程1的工作区中执行了number++.执行后将number的值更新成了1,写回到主内存中了。这个时候正要或者正在通知其他CPU主内存中的number值变化了。CPU2和CPU3都收到通知了,将自己工作区的变量置为无效,重新从主内存获取到number=1的值。这个时候CPU4执行的也快,在还没有收到CPU1的通知的时候,就将自己运行后的number++的值也写回到了主内存中。其实这个时候,cpu1线程1的操作还在进行中,但是因为cpu4线程4的操作打断了线程1的操作。第一轮运行结果应该是4,但是因为线程4把线程1执行打断了,将线程1执行结果覆盖了。所以实际执行后的效果有可能是3或者2但是不可能是4.

从上分析结果,我们更能理解到volatile修饰的共享变量不能保证原子性了。因为有可能被其他线程打断执行。

怎么解决原子性问题呢?可以使用juc包下的atomic包下的对象就可以了。

Volatile的有序性证明,欢迎学习下一篇:《Java并发编程之验证volatile指令重排-理论篇》

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

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

相关文章

搜狐视频怎么清除应用缓存

今天继续给大家分享搜狐视频方面的内容。搜狐视频播放器是播放器家园网小编用过最好用的一款,在这里能够不同类型的电视剧和电影,都是采用了4K级高清画质,让你随时感受到电影级别的视觉盛宴!搜狐视频客户端支持边下载边观看,云同步…

mysql 漏洞如何修复_Mysql漏洞修复方法思路及注意事项

【系统环境】系统环境:Red Hat Enterprise Linux Server release 5.4 (Tikanga) 5.7.16 MySQL Community Server (GPL)【漏洞信息】漏洞信息报告,根据集团第三方软件扫描出对应数据库版本的漏洞信息,可以从DVE号跟当前数据库发布版本时间来判…

爱奇艺视频怎么联系在线人工客服?

爱奇艺视頻是一款非常好的视頻,播放器家园网小编在闲的无聊的情况下,便会应用爱奇艺看来视頻,坚信大家也会应用爱奇艺视頻看来视頻,我们在应用爱奇艺的情况下,便会碰到些难题,今日小编给你详细介绍下&#…

java callback 多线程_JAVA Callback效率测试

在最近的联网电商项目中,想要实现单个web容器内的支付请求,全部能够统一宏观上同步,实现粒度上面异步,找来找去,没有相关方面的框架或者方案,于是最后基于现实场景,打算使用Java callback 的多线…

腾讯视频下载格式_怎么下载腾讯视频

不管这个腾讯视频好用与否,都有一大批用户,本文播放器家园网小编分享腾讯视频下载格式_怎么下载腾讯视频。腾讯视频时刻为您推荐最新最火的视频,精彩不断随时观看。支持各种画质的下载,没网也能享受高视觉的享受,让生活…

腾讯视频下载官方_腾讯视频评论在哪

本文给大家整理了腾讯视频下载官方_腾讯视频评论在哪方面的内容。腾讯视频影音是一款界面轻松友好,功能全面完善,方便好用,绿色安全,完全免费的、专注视频播放的客户端软件,您可运行腾讯视频影音,在线享受腾…

java 复写_课程5.4之函数的复写(override)

本节课程将学习以下内容:函数的复写(override)使用super调用父类的成员函数函数的复写(override)复写(override),也被称为覆盖或者重写。在你对父类的成员方法不满意的时候,你可以在子类中复写这个方法,来写出符合自己要求的方法。…

mongodb与java连接_MongoDBJava连接

Java 连接MongoDB package mymaven;import java.net.UnknownHostException;import java.util.Set;import com.mongodb.BasicDBObject;import com.mongodb.DB;import com.mongodb.DBCollection;import com.mongodb.DBCursor;import com.mongodb.DBObject;imporJava 连接MongoDBp…

糖果浏览器和139邮箱巧妙应用:将网页文字一键发送到手机上

核心提示:我们有时需要将一些网页中的文字发送到手机上,如商务会谈前,将出行路线和目的地地址发送到手机上便于查看。但是每次都需要手动录入到手机上,费时费力。 我们有时需要将一些网页中的文字发送到手机上,如商务…

Java飞机大战敌机消失_Shoot 飞机大战,功能是子弹打在敌机上, 消失 且在内存中 , 小蜜蜂上同理 Games 游戏 247万源代码下载- www.pudn.com...

文件名称: Shoot下载 收藏√ [5 4 3 2 1 ]所属分类: Games开发工具: Java文件大小: 371 KB上传时间: 2015-12-01下载次数: 0提 供 者: 刘星详细说明:飞机大战,功能是子弹打在敌机上,子弹消失敌机消失且在内存中消失,打在小蜜…

UC浏览器云标签怎么用 UC浏览器云标签使用方法

核心提示:相信很多机友都会使用UC浏览器,但是其多个功能你们能了解多少? 下面小编就为大家介绍UC浏览器云标签使用方法吧! 1、打开【UC浏览器】,点击【多窗口】按钮,然后点击【云标签】;(如下图所示) 2、登陆微博、QQ等&#…

谷歌浏览器怎么设置主页教程

谷歌浏览器怎么设置主页教程 谷歌浏览器怎么设置主页?目前,在世界范围内谷歌浏览器成为了仅次于ie浏览器的第二大主流浏览器,那么,谷歌浏览器主页怎么设置呢?针对此问题,下文浏览器家园小编就为大家图文介绍一下xx谷歌浏览器设置…

日志分析告警实现java_关于Aborted connection告警日志的分析

前言:有时候,连接MySQL的会话经常会异常退出,错误日志里会看到"Got an error reading communication packets"类型的告警。本篇文章我们一起来讨论下该错误可能的原因以及如何来规避。1.状态变量Aborted_clients和Aborted_connects…

UC浏览器APP如何卸载插件

现在很多用户在使用浏览器的时候都会安装一些插件辅助使用,方便用户享受更多便捷的功能,很多用户都会安装相关的插件服务,方便用户更好的使用,那么在用户不需要这些插件的时候要如何删除呢?今天小编就会与大家一起来分享一下浏览…

java在控制台输出sql_logger4j配置数据库sql输出控制台

#--------------------------------# 设定logger的root level为DEBUG/ERROR/info,指定的输出目的地(appender)为stdoutlog4j.rootLoggerERROR, stdout, fileout#log4j.logger.testinfo#log4j.logger.org.apache.jasper DEBUG#log4j.logger.org.apache.catalina.sta…

爱奇艺2020官方下载_爱奇艺视频如何上传

软件是否好用,还得大家下载爱奇艺安装才知道。本文分享爱奇艺2020官方下载_爱奇艺视频如何上传。爱奇艺电影频道拥有大量高清在线电影资源,热门高清电影、好评电影、电影预告都可以在线观看,不去电影院也能看好电影,而且是看所有电…

网页java在div输出内容_JS实现读取xml内容并输出到div中的方法示例

本文实例讲述了JS实现读取xml内容并输出到div中的方法。分享给大家供大家参考,具体如下:note.xml文件结构:GeorgeJohnReminderaJohnReminderGeorgeJohnReminder利用js将xml输出到div中:www.jb51.net js读取xml.aaaa{width: 30%;height: 50px;…

如何在优酷官网上传视频

当拍攝或是自做的视頻要想发送到在网上时,优酷视频便是一个非常好的视频网站,那如何把视频上传入优酷视频上呢? 01、 网站搜索并进到优酷官网。 如何在优酷官网上传视频 02、 在优酷主页点一下右上方的“登陆”标志,键入登录密码登陆优酷…

java枚举加载顺序_java 中类的加载顺序(转)

1、虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化2、只有在调用new方法时才会创建类的实例3、类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始化块部分,然后是父类的构造方法…

PP视频如何关闭下载完成通知我

播放器软件很多,本文小编给大家推荐PP视频。PP视频以优质的纯网内容,多元、贴心的生活服务态度,为用户打造一个人与服务相连接的全方位移动视频平台。大家通过PP视频播放器,可以观看到PP视频网站上的所有影视剧等视频资源。目前PP…