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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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

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

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

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

java相遇问题_两车追及或相遇问题(hdu1275)数学题

两车追及或相遇问题Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 902 Accepted Submission(s):259Problem Description外号叫“猪头三”的小学生在数学课上,经常遇到两车相遇或追及的方程题,…

java常用class类_java常用类

java常用类内部类1.成员内部类:在一个类的内部定义一个完整的类例如:外部类public class Body{内部类class Header{}}内部类可以直接访问外部类的私有成员,而且不破坏封装内部类可以为外部类提供必要的功能组件,成员内部类 在类的…

mysql 分类计数器_PHP MySQL映像计数器

我是PHP新手,一直在研究计数器.计数器很好用,但是现在我想将数字转换成图像.我创建了12张图片0-9,一个空格和一个逗号图片.我在上下搜索,以获取将数字格式转换为图像所需的提示,但没有成功.到目前为止,我所发现的就是如何仅使用文件PHP / MySQL来建立基本的计数器,以及如何使用…

java gc时会暂停运行吗,java gc 项目终止运行

当前位置:我的异常网 编程 java gc 项目终止运行java gc 项目终止运行www.myexceptions.net 网友分享于:2013-09-03 浏览:6次java gc 项目停止运行首先感谢阿宝同学的帮助,我才对这个gc算法的调整有了一定的认识,而不是停留在过…

php 取消页面一些样式,jquery如何去除样式

jquery去除样式的方法:1、使用【removeClass()】方法,代码为【removeClass(function(index,class))】;2、使用toggleClass方法,代码为【toggleClass(class)】。本教程操作环境:windows7系统、jquery3.2.1版&#xff0c…

matlab对经济指标分析,经济背景下的数据预测分析--基于matlab建模(郑铿城)

1、经济预测概述经济预测有三个要素,实际资料是预测的依据;经济理论是预测的基础;数学模型是预测的手段;经济预测的内容包括生产和资源预测,市场预测,国民收入分配预测,居民生活质量预测等。预测…

php nginx 静态资源,Nginx实践篇(1)- Nginx作为静态资源web服务 - 静态资源压缩

一、静态资源web服务1. 静态资源类型类型文件类型浏览器端渲染HTML、CSS、JS图片JEPG、GIF、PNG视频FLV、MPEG文件TXT等其他下载文件2. 静态资源服务场景-CDN二、静态资源核心配置1. 文件读取 sendfilesendfile 是一种高效传输文件的模式.sendfile设置为on表示启动高效传输文件…

php将get传参解析成数组,php解析url (parse_url) 参数成数组 (parse_str)

今天首先让我们为天津8.12大爆炸和陕西山阳山体滑坡遇难的同胞默哀3分钟,祝愿受伤的群众早日康复,脱离危险,希望国家严惩事故责任人,安抚受损群众。希望杯具以后不再发生……最近天灾人祸,大家出行一定要注意安全&…

猛将赵云java,这五位三国猛将临危救主,赵云只能排第二位,第一位大家都服...

曹洪,曹子廉。是曹操的从弟,在《三国演义》小说中,最早跟随曹操起兵,虽然战斗力没有一流战将那么强悍,但是此人在曹操起兵讨伐董卓时,曹操在荥阳被徐荣打败,坐骑丢失。正要被徐荣士兵解决的时刻…

用python画三维图、某区域的高程,python - 在PyQt中绘制具有高程和降低效果的3D矩形/多边形 - SO中文参考 - www.soinside.com...

据我所知,没有内置的PyQt 3D绘制小部件/功能,因为您只能绘制2D多边形。但我们可以创建一个自定义类来模拟3D绘画。从您的Java链接reference:Java支持3D矩形,但第三维的效果不是很明显。由于海拔较低,效果可以忽略不计。…

2024年PMP考试新考纲-PMBOK第七版-项目管理原则真题解析(续3)

马上就要进入2024年了,要参加2024年PMP一季度考试的小伙伴可以准备起来了。2024年的PMP考试将继续采用新考试大纲,考试内容包括PMBOK第六版、PMBOK第七版和敏捷实践指南,而且敏捷(或者叫混合)的项目环境将占比超过50%&…

linux 串口信息记到日志,[linux学习笔记]之一:ubuntu ch340调试备忘

[linux学习笔记]之一:ubuntu ch340调试备忘已有 2183 次阅读2016-11-8 21:52|个人分类:linux最近迷上了Linux,入了一块板。电脑使用win7ubuntu 双系统,可是调试的时候就麻烦了,ubuntu下写好sd卡镜像,调试的时候还要切换…

嵌入式linux 配置usb otg,嵌入式linux系统环境下USB设备的驱动实现

0 引言嵌入式linux系统环境以其易于移植裁减、内核小、效率高、完整、原代码开放及性能优异等特点,在嵌入式领域得到了非常广泛的应用。Linux的USB设备端的源代码中主要有USB device的海量存储设备、串口设备、网络设备等设备驱动程序及各种USB device控制器芯片的…

linux 上下文切换监控,[Linux] 查看进程的上下文切换pidstat

各个进程之间是共享 CPU 资源的,在不同的时候进程之间需要切换,让不同的进程可以在 CPU 执行,那么这个一个进程切换到另一个进程运行,称为进程的上下文切换。进程是由内核管理和调度的,所以进程的切换只能发生在内核态…

linux怎么休眠快捷键,在Deepin系统中创建右键休眠选项的方法

本文介绍在深度Deepin操作系统中创建右键休眠选项,以方便你更快的进入到系统休眠当中,实现方法非常简单,按照下面的步骤进行就可以了。休眠的好处系统休眠,可以让平时的工作环境保存到硬盘中,以便开机后便可立即进入工…