当前位置: 首页 > news >正文

JavaEE 第6节 内存可见性问题以及解决方法

目录

一、什么是内存可见性问题?

1、问题代码演示

2、基础知识铺垫

1)硬件层面

2)模型层面(JMM)

二、内存可见性问题的原因

三、volatile解决内存可见性问题


一、什么是内存可见性问题?

1、问题代码演示

public class Threads {static int count = 0;//实现加锁private synchronized static void add() {count++;}public static Object object1=new Object();public static Object object2=new Object();public static int n=0;public static void main(String[] args) throws InterruptedException {Thread thread1=new Thread(()->{while(n==0){//什么都不做}System.out.println("while循环结束");});Runnable runnable=new Runnable() {@Overridepublic void run() {System.out.println("修改n的值为非0");Scanner scanner=new Scanner(System.in);n=scanner.nextInt();System.out.println("修改完成");}};Thread thread2=new Thread(runnable);thread1.start();thread2.start();thread1.join();thread2.join();}}

按照代码逻辑,我们在终端输入一个1,那么就会打印"while循环结束",但实际情况真是如此吗?

请看执行结果:

在输入一个1之后,程序并没有结束(正方形红点),那么就说明这个程序是有bug的。

2、基础知识铺垫

1)硬件层面

想要理解这个bug产生的原因,需要简单了解计算机的存储结构以及它们的特性:

寄存器(Register):访问速度最快,但存储的数据最少,掉电后数据丢失。

高速缓存(Cache):访问速度中等,存储数据中等,掉点后数据丢失。

硬盘(Hard Drive):访问速度最慢,存储数据最多,掉点后数据不会丢失。


Cache和Register都是CPU上的一部分,Cache还可以细分成多级缓存。

Register\Cache\Hard Drive这三者之间访问速度和存储大小差距是非常大的,都是按照数量级进行换算的,这就导致不同的硬件访问数据的速度会有质的不同

2)模型层面(JMM)

Java内存模型(Java Memory Model,JMM)是Java虚拟机(JVM)规范的一部分。它规定了多线程环境下,每个线程访问共享内存的方式,这个模型的主要目标是保证程序员能够在多线程环境下编写出正确高效的程序。

接下来用一张图描述JMM的具体要求:

这里的本地内存指的就是Working Memory,相当于刚才硬件部分介绍的寄存器(Register)以及高速缓存(Cache)。主内存就是Main Memory,相当于刚才硬件部分介绍到的硬盘(Hard Drive)。

在JMM的控制下,线程与线程使用的内存不是物理层面的共享,他们都分别从Main Memory的共享内存区域,拷贝一份副本到自己的Working Memory。

二、内存可见性问题的原因

从刚才的图示中可以知道,想要实现两个线程t1,t2之间的通信需要两步:

1.t1修改了对应变量然后把Working Memory同步更新会Main Memory

2.t2从Main Memory更新Working Memory保证使用的数据是正确的

还记得刚才的代码吗?

t1的while循环中什么都没有写,因此这个空循环的执行速度是非常快的,可能一秒执行几千甚至上万次。这时编译器看不下去了,因为n这个变量是在Main Memory上的(每次的读取速度非常慢),编译器为了优化代码,让t1直接去自己的Working Memory去读取变量n,进而提高代码的执行效率,但这样就会导致内存可见性问题:

三、volatile解决内存可见性问题

volatile的其中一个英文意思是:易变的

也就是说这个关键字修饰的变量,可以告诉编译器不要在Working Memory上读,那里不准确,必须在硬盘上(Main Memory)上读这个数据,因为这个数据很容易改变,一旦改变,Working Memory上有没有及时更新,会产生问题的!

具体用法

public class Threads {static int count = 0;//实现加锁private synchronized static void add() {count++;}public static volatile int n=0;//代码只在这里多加了volatile修饰变量public static void main(String[] args) throws InterruptedException {Thread thread1=new Thread(()->{while(n==0){//什么都不做}System.out.println("while循环结束");});Runnable runnable=new Runnable() {@Overridepublic void run() {System.out.println("修改n的值为非0");Scanner scanner=new Scanner(System.in);n=scanner.nextInt();System.out.println("修改完成");}};Thread thread2=new Thread(runnable);thread1.start();thread2.start();thread1.join();thread2.join();}
}

执行结果:

相关文章:

JavaEE 第6节 内存可见性问题以及解决方法

目录 一、什么是内存可见性问题? 1、问题代码演示 2、基础知识铺垫 1)硬件层面 2)模型层面(JMM) 二、内存可见性问题的原因 三、volatile解决内存可见性问题 一、什么是内存可见性问题? 1、问题代码…...

es基本操作

以下是一些 Elasticsearch 常用的命令,涵盖了索引管理、数据操作和集群管理等方面: 基本操作 检查集群状态: curl -X GET "localhost:9200/_cluster/health?pretty"查看集群健康状态和基本信息。 查看所有索引: curl…...

开源 AI 智能名片 S2B2C 商城小程序赋能下的社区团购商业模式研究

摘要:本文深入探讨了社区团购商业模式的本质、特点及其优势,并详细分析了开源 AI 智能名片 S2B2C 商城小程序在社区团购中的应用与价值。通过对相关案例的研究和数据的分析,揭示了这一创新组合对社区商业生态的重要影响,为未来社区…...

AutoSar AP软件规范中CM介绍及功能概要

1. 前言 为了理解AutoSar AP中EM的概念,生搬硬套的翻译了《 AUTOSAR SWS CommunicationManagement.pdf》的介绍部分,并按照自己的理解进行了修改。如下 2. AUTOSAR_SWS_CommunicationManagement.pdf的介绍部分 本文件包含AUTOSAR AP通信管理的功能、A…...

【图形学】TA之路-向量

向量 向量 是一个有大小和方向的数学对象。在三维空间中,向量通常表示为 (v_x, v_y, v_z)。 基本操作 加法: a b (a_x b_x, a_y b_y, a_z b_z)减法: a - b (a_x - b_x, a_y - b_y, a_z - b_z)标量乘法: k * v (k * v_x, …...

[flink]部署模式

部署模式 在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。 Flink为各种场景提供了不同的部署模式,主要有以下三种:会话模式(Session Mode)、单作业模式(Per-Job Mode&…...

为什么不用postman做自动化

面试的时候被问到:为什么不用postman做自动化 打开postman,看到用例集管理、API 管理、环境管理这三个功能,用户体验感算得上品牌等级了 为什么不用呢,文心一言给了一些答案 不适合大规模自动化测试:Postman 主要是为…...

一、Matlab基础

文章目录 一、Matlab界面二、Matlab窗口常用命令三、Matlab的数据类型3.1 数值类型3.2 字符和字符串3.3 逻辑类型3.4 函数句柄3.5 结构类型3.6 细胞数组 四、Matlab的运算符4.1 算术运算符4.2 关系运算符4.3 逻辑运算4.4 运算符优先级 五、Matlab的矩阵5.1 矩阵的建立5.2 矩阵的…...

执行java -jar命令,显示jar中没有主清单属性

在Java中,一个"主清单属性"(Main-Class attribute)是指定JAR文件中包含的应用程序入口点,即包含main方法的类的完全限定名。如果你尝试运行一个没有主清单属性的JAR文件,你可能会看到错误消息,如…...

【C++进阶】红黑树

目录 什么是红黑树?红黑树红黑树的性质 定义红黑树红黑树的操作insertinorderfindheightsize构造函数析构函数赋值拷贝判断红黑树 全部代码总结 什么是红黑树? 红黑树 红黑树(Red-Black Tree)是一种自平衡的二叉搜索树&#xff…...

linux使用ssh连接一直弹出密码框问题

1.查看ssh服务的状态 输入以下命令: sudo service sshd status 小编已经安装了。 如果出现 Loaded: error (Reason: No such file or directory) 提示的话,说名没有安装ssh服务,按照第二步:安装ssh服务。 如果出现 Active: in…...

Python 3 数据结构

Python 3 数据结构 引言 Python 是一种高级编程语言,因其简洁明了的语法和强大的功能而广受欢迎。在 Python 中,数据结构是组织和存储数据的方式,对于编写高效和可维护的代码至关重要。本文将深入探讨 Python 3 中的主要数据结构&#xff0…...

【开源社区】Elasticsearch(ES)中空值字段 null_value 及通过exists查找非空文档

文章目录 0、声明1、问题描述2、问题剖析2.1 NULL或者空值类型有哪些2.2 案例讲解:尝试检索值为 null 的字段2.3 解决思路 3、使用 null_value 的诸多坑(避免生产事故)3.1 null_value 替换的是索引,并不会直接替换源数据3.2 不支持…...

JavaDS —— 位图(BitSet)与 布隆过滤器

位图 引入问题:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 首先要注意 40 亿个数据如果使用 整型(int) 来存放的话,就是要 40 亿个整型,一个整型有…...

如何确保场外个股期权交易的安全?

如何确保场外个股期权交易的安全?投资者可以采取以下措施,以提高交易的安全性和减少风险: 增强知识储备:深入学习期权的基础知识,包括不同类型的期权、它们的权利和义务、定价方式以及风险特性,从而提升自…...

第2章:LabVIEW FPGA未来发展方向《LabVIEW ZYNQ FPGA宝典》

2.1:NI的LabVIEW FPGA未来战略部署 在展望NI公司的LabVIEW FPGA技术未来发展趋势之前,让我们先来回顾一下LabVIEW与FPGA的技术发展历程,如图2-1所示。可以看出,NI公司的LabVIEW FPGA软件一方面是跟随Xilinx最新的FPGA硬件可持续发…...

苹果电脑维护工具:CleanMyMac X让你的Mac焕发新生!

在我们的数字生活中,苹果电脑(Mac)已成为不可或缺的一部分,无论是为工作披星戴月,还是为娱乐畅游云端。但是,就像任何长时间运行的机器一样,Mac也可能会因为积累的文件和不必要的数据而开始变慢…...

MySQL2 DML数据操纵语言和SQL约束

DML和SQL约束 SQL-DML1.添加数据2.修改数据3.删除 TRUNCATE和DELETE的区别:SQL-约束Primary Key创建主键约束单列主键联合主键**验证主键约束**删除主键约束设置主键自增AUTO_INCREMENTdelete和truncate删除后,主键的自增 SQL-唯一约束UNIQUE创建唯一约束…...

Ubuntu 20.04 中安装 Nginx (通过传包编译的方式)、开启关闭防火墙、开放端口号

文章目录 前言一、安装包下载二、上传服务器并解压缩三、依赖配置安装四、生成编译脚本五、编译六、查看是否编译完成七、开始安装八、查看是否安装成功九、设置为开机自启动 前言 参考大佬文章并在基础上做了点修改,发篇文章记录下 防止下次遇到。 参考文章&#…...

解决no main manifest attribute错误

文章目录 0. 背景1. java程序如何运行2. jar是什么3. java -jar test-1.0-SNAPSHOT.jar:4. 添加执行入口 0. 背景 在开发Spring boot项目的时候,有时候会需要使用java -jar test-1.0-SNAPSHOT.jar指令来运行开发的java应用,但是很不幸&#…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点

中科院1区顶刊|IF14&#xff1a;多组学MR联合单细胞时空分析&#xff0c;锁定心血管代谢疾病的免疫治疗新靶点 当下&#xff0c;免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入&#xff0c;我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...