volatile 无法保证原子性 案例展示

volatile 无法保证原子性

  • 在 Java 中,原子性是指一个操作是不可中断的,要么都执行要么都不执行。

  • 但是 volatile 修饰的变量,只是保证了从主内存加载到工作内存的值是最新的,并不能保证对变量的操作是原子性的

  • 变量的写操作和读操作之间是可以被中断的,也就是在读取或者修改 volatile 变量的过程中,其他线程可能会对这个变量进行修改,

  • 所以在多线程环境下,对线程的操作结果可能会丢失,想要在多线程情况下修改主内存的共享变量必须加锁来保持同步

例如:

  • 一个变量i被volatile修饰,两个线程想对这个变量修改,都对其进行自增操作也就是i++,i++的过程可以分为三步,首先获取i的值,其次对i的值进行加1,最后将得到的新值写会到缓存中。
  • 线程A首先得到了i的初始值100,但是还没来得及修改,就阻塞了
  • 这时线程B开始了,它也得到了i的值,由于i的值未被修改,即使是被volatile修饰,主存的变量还没变化,那么线程B得到的值也是100,之后对其进行加1操作,得到101后,将新值写入到缓存中,再刷入主存中。根据可见性的原则,这个主存的值可以被其他线程可见。
  • 此时,线程A已经读取到了i的值为100,也就是说读取的这个原子操作已经结束了,所以这个可见性来的有点晚,线程A阻塞结束后,继续将100这个值加1,得到101,再将值写到缓存,最后刷入主存,所以即便是volatile具有可见性,也不能保证对它修饰的变量具有原子性。
    private static  volatile   Integer i = 0;public static void test2() throws Exception {new Thread(() -> {System.out.println(Thread.currentThread().getName()+"读取的i为:"+i);try { Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}i = i +1;System.out.println(Thread.currentThread().getName()+"计算的i为:"+i);}, "线程A").start();new Thread(() -> {System.out.println(Thread.currentThread().getName()+"读取的i为:"+i);try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}i = i +1;System.out.println(Thread.currentThread().getName()+"计算的i为:"+i);}, "线程B").start();Thread.sleep(100);System.out.println("主线程执行结束,此时in为:" + i);}

例如:下面的代码不管加不加 volatile ,执行结果都会出错请添加图片描述

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

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

相关文章

OS 进程同步

基本概念 定义:把异步环境下的一组并发进程因直接制约而相互发送消息、相互合作、相互等待,使得各进程按一定的速度执行的过程,称为进程同步 协作进程:具有同步关系的一组并发进程 进程同步机制的主要任务:在执行次…

laravel-admin导出excel全部,表中无id列导出失败

laravel-admin导出excel时,导出全部数据,但是表中没有id字段,然后就无法导出excel; 就直接显示 一开始我也很着急,弄了半天还是不行,然后重写还是有问题 最后发现底层代码排序是按照id排序的orderBy(id, a…

SPASS-偏相关分析

基本概念 偏相关分析的任务就是在研究两个变量之间的线性相关关系时控制可能对其产生影响的变量,这种相关系数称为偏相关系数。偏相关系数的数值和简单相关系数的数值常常是不同的,在计算简单相关系数时,所有其他自变量不予考虑。 统计原理 控制一个变量和控制两个变量的偏…

数据结构与算法-图

图 🎈2.图的存储结构📖2.4.2邻接表的存储✅2.4.2.1逆邻接表✅2.4.2.2邻接表存储结构的定义✅2.4.2.3邻接表存储结构的类定义✅2.4.2.4创建n个顶点m条边的无向网✅2.4.2.5创建n个顶点m条边的有向网✅2.4.2.6定位操作-查找定点信息在顶点数组中的下标✅2.4…

操作系统:操作系统教程第六版(骆斌、葛季栋、费翔林)习题一计算机操作系统概述

目录 前言1. 思考题2. 应用题 前言 本系列文章是针对操作系统教程第六版(骆斌、葛季栋、费翔林)的习题解答,其中简答题部分为博主自己搜索整理的,错漏之处在所难免。应用题部分有答案为依据。 1. 思考题 (1&#xf…

【深度学习实验】注意力机制(一):注意力权重矩阵可视化(矩阵热图heatmap)

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 理论介绍a. 认知神经学中的注意力b. 注意力机制: 1. 注意力权重矩阵可视化(矩阵热图)a. 导入必要的库b. 可视化矩阵热图(show_heatmaps&#xff0…

pythongui实时闹钟

# codinggbk import tkinter as tk from time import strftime# 创建一个主窗口 root tk.Tk() root.title("实时闹钟")# 设置窗口的大小不可变 root.resizable(False, False)# 设置窗口始终保持在最上层 root.attributes(-topmost, True)# 更新时间的函数 def time(…

三菱PLC 模拟量输出模拟量转换功能块S_RTI(内嵌ST)

模拟量输出模拟量转换功能块S_RTI算法原理和公式介绍请参考下面文章链接: PLC模拟量输出 模拟量转换FC S_RTI-CSDN博客文章浏览阅读5.3k次,点赞2次,收藏11次。1、本文主要展示西门子博途模拟量输出转换的几种方法, 方法1:先展示下自编FC:计算公式如下:intput intput Rea…

大模型的语言能力

NLP作为一个领域为基础模型开辟了道路。虽然这些模型在标准基准测试中占据主导地位,但这些模型目前获得的能力与那些将语言描述为人类交流和思维的复杂系统的能力之间存在明显的差距。针对这一点,我们强调语言变异的全部范围(例如&#xff0c…

元素水平垂直居中

方法一&#xff1a;定位transform 方法二&#xff1a;flex布局 方法三&#xff1a;定位margin【需要child 元素自身的宽高】 相关HTML代码&#xff1a; <div class"parent"><div class"child"></div> </div> 方法一&#xff1a…

华媒舍:怎样成为谷歌竞价排名羸家?10个方法

谷歌竞价排名是一种线上广告方式&#xff0c;企业通过推广广告来提高在搜索结果中的排名。这类排名方法帮助企业吸引更多浏览量和潜在用户。以下属于10个能够帮助你在谷歌竞价排名中获得成功的基石方法&#xff1a; 关键字科学研究&#xff1a;挑选与你产品和服务相关的关键词至…

k8s的高可用集群搭建,详细过程实战版

kubernetes高可用集群的搭建 前面介绍过了k8s单master节点的安装部署 今天介绍一下k8s高可用集群搭建 环境准备&#xff1a; vip &#xff1a;192.168.121.99 keeplive master01&#xff1a;192.168.121.153 centos7 master02&#xff1a;192.168.121.154 centos7 master03&a…