Java内存模型与volatile

news2024/11/28 16:51:37

Java内存模型

Java内存模型Java Memory Model,简称JMM,本身是一种抽象的概念并不真实存在它仅仅描述的是一组约定或规范,通过这组规范定义了程序中(尤其是多线程)各个变量的读写访问方式并决定一个线程对共享变量的写入何时以及如何变成对另一个线程可见,关键技术点都是围绕多线程的原子性可见性有序性展开的。

JMM规范下,三大特性

  • 原子性
  • 可见性
  • 有序性
原子性

指一个操作是不可中断的,即多线程环境下,操作不能被其他线程干扰。

可见性
  • ​ Java中普通的共享变量不保证可见性,因为数据修改被写入内存的时机是不确定的,多线程并发下很可能出现"脏读"。

  • 每个线程都有自己的工作内存,线程自己的工作内存中保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取,赋值)都必需在线程自己的工作内存中进行,而不能够直接读写主内存中的变量。

在这里插入图片描述

有序性
  • 对于一个线程的执行代码而言,我们总是习惯性认为代码的执行总是从上到下,有序执行。 但为了提供性能,编译器处理器通常会对指令序列进行重新排序。

  • 指令重排可以保证串行语义一致,但没有义务保证多线程间的语义也一致,即可能产生"脏读"。

总结
  • 我们定义的所有共享变量都储存在物理主内存中
  • 每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝)
  • 线程对共享变量所有的操作都必须先在线程自己的工作内存中进行后写回主内存,不能直接从主内存中读写(不能越级)
  • 不同线程之间也无法直接访问其他线程的工作内存中的变量,线程间变量值的传递需要通过主内存来进行(同级不能相互访问)

volatile

关键字,保证不同线程对这个变量进行操作时的可见性,即变量一旦改变所有线程立即可见,指令禁重排,不能保证原子性。

  • 可见性
  • 有序性

volatile凭什么可以保证可见性和有序性???

内存屏障 (Memory Barriers / Fences),是一种屏障指令,它使得CPU或编译器对屏障指令的前和后所发出的内存操作执行一个排序的约束。也叫内存栅栏或栅栏指令。

  • 阻止屏障两边的指令重排序
  • 写数据时加入屏障,强制将线程私有工作内存的数据刷回主物理内存
  • 读数据时加入屏障,线程私有工作内存的数据失效,重新到主物理内存中获取最新数据
屏障类型

在这里插入图片描述

写屏障
  • 在每个 volatile 写操作的前⾯插⼊⼀个 StoreStore 屏障

  • 在每个 volatile 写操作的后⾯插⼊⼀个 StoreLoad 屏障

读屏障
  • 在每个 volatile 读操作的后⾯插⼊⼀个 LoadLoad 屏障
  • 在每个 volatile 读操作的后⾯插⼊⼀个 LoadStore 屏障
volatile可见性

volatile关键字保证可见性,意味着∶

  • 对一个volatile修饰的变量进行读操作的话,总是能够读到这个变量的最新的值,也就是这个变量最后被修改的值

  • 一个线程修改了volatile修饰的变量的值的时候,那么这个变量的新的值,会立即刷新回到主内存中

  • 一个线程去读取 volatile 修饰的变量的值的时候,该变量在工作内存中的数据无效,需要重新到主内存去读取最新的数据

volatile有序性
  • volatile 写之前的操作,都禁止重排序到volatile之后
  • volatile读之后的操作,都禁止重排序到volatile之前
  • volatile 写之后的操作,都禁止重排序到volatile之前

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

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

相关文章

白鹭群优化算法(ESOA)附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

单调区间能写成并吗?【基于间断区间的讨论】

不能。 问题 在做到一道题的时候,发现了两个减区间,于是就用并∪连接到一起了,但是答案是要用和连接。于是想要辨析一下这个并和和的区别。 区别 并:并的意思是将多个区间看成一个并起来的整体,在整个区间上仍然是…

按照 STAR 法则介绍自己做过的项目

大家好啊,我是大田 介绍项目注意两点:1、自己真的做过 2、逻辑表达能力 为什么推荐你用 STAR 法则说呢? STAR 法则是结构化面试中非常重要的理论。 面试官通过这样的描述全面了解你的测试知识、经验、技术能力的掌握程度,通过你发…

本地pycharm连接到远程服务器(超级详细)

本地pycharm连接到远程服务器(超级详细) 文章之前,你需要做的是 1.服务器需要创建好虚拟环境 2.你的本地安装好pycharm 目的是 同步服务器上的文件 在本地进行debug,并将修改后的文件进行更新 一般是将文件代码上传到服务器上面&…

【微服务】Sentinel 控制台

目录 1. 概述 2. 启动控制台 2.1 获取 Sentinel 控制台 2.2 启动 3. 客户端接入控制台 3.1 引入JAR包 3.2 配置启动参数 3.3 触发客户端初始化 4. 查看机器列表以及健康情况 5. 监控 5.1 "簇点链路"中显示刚刚调用的资源(单机实时) …

猿创征文|分享一下我的日常开发工具和常用软件

1、Eclipse IDE for Java Developers 这个软件,个人已经用了很多年的免费 Java 开发软件。 1)配置JDK 2)新建项目 3)运行使用 这里注意到有 Run As 和 Debug As ,区别就是后者是调试模式,你可以在代码任意处打断点跟…

element-ui中获取el-divider的组件的ref时为空

element-ui中的el-divider组件是函数式组件,所以当我尝试获取其ref时总是获取不到,因为函数式组件没有this. ![在这里插入图片描述](https://img-blog.csdnimg.cn/496711bf5c2a4dd1bee168e4e2d638d4.png)此时打印this.$refs,控制台输出: 没有h2,翻看el-divider源码发现是函数式…

C++入门学习3-指针与字符数组,函数,指针数组

c入门学习3char型指针的使用p*p*p与p与[整型指针指向整型数组]的区别指针与函数的使用指向函数的指针空指针调用函数从函数中返回指针一维数组和二维数组的类比CHAR型指针数组关于&achar型指针的使用 char型指针可以直接指向一个字符串,如下 char s[]{a,b,c};…

YOLO V7源码解析

1.命令行参数介绍 YOLO v7参数与YOLO v5差不多,我就直接将YOLO v5命令行参数搬过来了,偷个懒 --weights:初始权重--cfg:模型配置文件--data:数据配置文件--hyp:学习率等超参数文件--epochs:迭代次数-imgsz:图像大小--rect:长方…

多目标蜉蝣优化算法(MOMA)附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

统计信号处理基础 习题解答6-6

题目 在本题中,我们扩展标量BLUE的结果。假定 其中θ 是待估计的未知参数,β 是已知常数,数据矢量x 的协方差矩阵是C 。在本题我们定义修正的线性估计量为 证明BLUE为: 另外求最小方差。 解答: 首先确保线性估计量是…

TFT-LCD显示中英文

TFT-LCD显示中英文 在前面编写了屏幕显示ASCII字符和字符串后,本次实现屏幕显示中文字符和中文字符串 中文字符取模 阴码,逐行式,逆向,十六进制数,C51格式, 输入要显示的中文字符,字体选择宋…

【数据结构】搜索二叉树(C++实现)

目录 一、二叉搜索树的概念 二、二叉搜索树的实现 2.1 节点的定义及构造 2.2 树的结构及功能展示 2.3 树的 Insert 2.4 树的中序遍历 2.4 树的 Find 2.5 树的 Erase 2.6 拷贝构造、赋值运算符重载、析构函数 三、递归实现树的增删查 3.1 递归实现 FindR 3.2 递归实…

Vue | Vue.js Composition API(二)

🖥️ Vue.js专栏:Vue.js 初级知识 Composition API(二) 🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 ✨ 个人主页:CoderHing的个人主页 🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀…

嘿,朋友,其实 CSS 动画超简单的 - 时间函数篇(贝塞尔曲线、steps,看完还不懂算我输)

分配内存 - new 官方定义:new是一个分配内存的内置函数,第一个参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针。 func new(Type) *Type 我们平常在使用指针的时候是需要分配内存空间的,未分配内存空间…

Java自定义注解

目录 一、什么是自定义注解 1)Java注解简介 2)Java注解分类 JDK基本注解 JDK元注解 自定义注解 如何自定义注解? 二、自定义注解 1)获取类上注解值 2)获取类属性上的注解属性值 3)获取方法上的注…

WireShark 常用协议分析

WireShark 常用协议分析 1.3 实战:使用 WireShark 对常用协议抓包并分析原理 协议分析的时候 我们 关闭混淆模式, 避免一些干扰的数据包存在。 1.3.1 常用协议分析 - ARP 协议 地址解析协议 (英语:Address Resolution Protocol&…

从内核角度看网络包发送流程

一、前置知识 1、RingBuffer结构详解 关于RingBuffer网上有很多说法,有的人说RingBuffer是系统启动时就预先申请好的一个环形数组,有的人说RingBuffer是在接收或发送数据时才动态申请的一个环形数组,那么到底RingBuffer的结构是怎么样的呢&…

《吉师作业》(2)之迟来的答案

前言 🍀作者简介:吉师散养学生,为挣钱努力拼搏的一名小学生。 🍁个人主页:吉师职业混子的博客_CSDN博客-python学习,HTML学习,清览题库--C语言程序设计第五版编程题解析领域博主 🫒文章目的:我不…

初识C++(二)

简述 :本篇就缺省参数 和 函数重载 方面进行初步学习 ,对比C语言学习C这两个语法,从而感受C在此方面对C语言进行的补充。 目录 缺省参数 什么是缺省参数 缺省参数的分类 缺省参数的应用 函数重载 什么是函数重载 函数重载的三种情况 支…