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

内存可见性

内存可见性

  • 一:内存可见性
    • 1.2:
  • 二:解决内存可见性问题
    • 2.1 volatile关键字
    • 2.2:synchronized关键字解决内存可见性问题

一:内存可见性

public class Demo1 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1=new Thread(()->{while(count==0){}System.out.println("t1线程结束");});Thread t2=new Thread(()->{Scanner scanner=new Scanner(System.in);1System.out.println("请输入一个整数:");count=scanner.nextInt();});t1.start();t2.start();}
}

上述代码预期效果:
t1线程首先进入循环,当用户输入一个非0整数的时候,就会使t1线程退出循环.结束线程.
但t1实际上并没有真正出现退出的情况,这也是"bug",而产生上述现象的原因,就是**“内存可见性”**

  while(count==0){}

从指令角度分析这段代码:
(1)load :从内存读取数据到CPU 寄存器中,
(2)cmp:比较,条件成立,继续循环,条件不成立,退出循环.
然而,一个load指令消耗的时间,会比一个cmp指令消耗的时间多得多,执行一次load的时间,等于上万次cmp执行消耗的时间.
同时,JVM发现每次load执行的结果,是一样的(t2线程修改之前),因此,**JVM就把上述load操作优化掉了,只是第一次真正进行load,后续再执行到load,而是直接读取已经load过的寄存器中的值了(读取寄存器的速度远远大于 读取内存的速度).**当t2线程修改count的值,但由于t1线程并没有从内存中重新读取,所以获取不到更新后的值.

1.2:

public class Demo1 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1=new Thread(()->{while(count==0){System.out.println("hello ");}System.out.println("t1线程结束");});Thread t2=new Thread(()->{Scanner scanner=new Scanner(System.in);System.out.println("请输入一个整数:");count=scanner.nextInt();});t1.start();t2.start();}
}

当我们在

 while(count==0){System.out.println("hello ");}

while循环中打印,就会发现代码又和我们预期的效果一样了,这又是为什么???
因为循环体内存在IO操作,而IO操作是从硬盘中获取数据,因此IO操作消耗的时间比load操作消耗的时间更多,并且IO操作是不能被优化掉的.
总结:上述问题本质上是编译器优化引起的(优化是由javac和java配合完成的工作),优化掉load操作之后,使t2线程的修改,没有被t1线程感知到,这就造成了"内存可见性"问题

二:解决内存可见性问题

2.1 volatile关键字

编译器什么时候优化,什么时候不优化,这是一个"玄学问题".
通过volatile关键字,解决优化问题,让编译器不再优化.
当给变量修饰上volatile关键字之后,编译器就知道了,这个变量是"反复无常"的,编译器就不会再进行优化了
volatile 是专门针对内存可见性的场景来解决问题的,告诉编译器不要进行优化操作.

public class Demo1 {public  volatile static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1=new Thread(()->{while(count==0){}System.out.println("t1线程结束");});Thread t2=new Thread(()->{Scanner scanner=new Scanner(System.in);System.out.println("请输入一个整数:");count=scanner.nextInt();});t1.start();t2.start();}
}

2.2:synchronized关键字解决内存可见性问题

synchronized关键字,和volatile关键字处理逻辑上是不同的.
引入synchronized关键字,是因为加锁操作本身太重量了,相比load 来说,开销更大,编译器自然就不会对load 优化了(和sleep ,IO操作原理类似).

public class Demo1 {public   static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1=new Thread(()->{while(count==0){synchronized (locker){{}}}System.out.println("t1线程结束");});Thread t2=new Thread(()->{Scanner scanner=new Scanner(System.in);System.out.println("请输入一个整数:");count=scanner.nextInt();});t1.start();t2.start();}
}

相关文章:

内存可见性

内存可见性 一:内存可见性1.2: 二:解决内存可见性问题2.1 volatile关键字2.2:synchronized关键字解决内存可见性问题 一:内存可见性 public class Demo1 {public static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1new Thre…...

Android room 在dao中不能使用挂起suspend 否则会报错

错误&#xff1a; Type of the parameter must be a class annotated with Entity or a collection/array of it. kotlin.coroutines.Continuation<? super kotlin.Unit> $completion); 首先大家检查一下几个点 一、kotlin-kapt 二、 是否引入了 room-ktx 我是2024年…...

【stable diffusion扩散模型】一篇文章讲透

目录 一、引言 二、Stable Diffusion的基本原理 1 扩散模型 2 Stable Diffusion模型架构 3 训练过程与算法细节 三、Stable Diffusion的应用领域 1 图像生成与艺术创作 2 图像补全与修复 3 其他领域 四、Stable Diffusion的优势与挑战 &#x1f449;优势 &#x1f…...

数据链路层之信道:数字通信的桥梁与守护者

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

SQL109 纠错4(组合查询,order by..)

SELECT cust_name, cust_contact, cust_email FROM Customers WHERE cust_state MI UNION SELECT cust_name, cust_contact, cust_email FROM Customers WHERE cust_state IL ORDER BY cust_name;order by子句&#xff0c;必须位于最后一条select语句之后...

Spring Boot + Vue 实现文件导入导出功能

文章目录 1、概述2、后端实现&#xff08;Spring Boot&#xff09;3、前端实现&#xff08;Vue&#xff09;4、总结 1、概述 ​ 在现代Web应用开发中&#xff0c;文件的导入导出是一个常见的需求。Spring Boot作为后端开发的强大框架&#xff0c;搭配前端框架Vue&#xff0c;可…...

vue watch 深度监听

vue2文档&#xff1a;API — Vue.js vue3文档&#xff1a;侦听器 | Vue.js watch 可以用来监听页面中的数据&#xff0c;但如果监听的源是对象或数组&#xff0c;则使用深度监听&#xff0c;强制深度遍历源&#xff0c;以便在深度变更时触发回调。 一&#xff0c;监听 <t…...

Qt源码调试步骤记录

1.源码&#xff1a; 两种方式&#xff0c;要么安装qt时选择source&#xff0c;要么从官网下载源码&#xff0c;然后在qt creator中设置路径。二选一即可。我选的第二种。 1.1.第一种&#xff0c;安装时选择source&#xff1a; 1.2.第二种&#xff0c;下载源码设置路径&#x…...

大数据面试英文自我介绍参考(万字长文)

发现有一个怪圈,如果码农年龄35+,除非非常匹配,不然在国内企业筛选可能就筛选不过。国外码农可以干到40+、50+。一些外企,对年龄35+的码农依然青睐。这些外企对英文是有要求,通常是要英文自我介绍,下面提供一些英文自我介绍参考。 参考1: Good morning/afternoon, I a…...

外包干了5天,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入杭州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

Docket常见的软件部署1

1 安装MySQL # 查看MySQL镜像 docker search mysql # 拉起镜像 docker pull mysql:5.7 # 创建MySQL数据映射卷&#xff0c;防止数据不丢失 mkdir -p /hmoe/tem/docker/mysql/data/ # 启动镜像 docker run -d --name mysql -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -v /home…...

Qt源程序编译及错误问题解决

Error 5 while parsing C:/qt-everywhere-src-6.6.2/qt-build/qtdeclarative/src/qmlmodels/meta_types/qt6qmlmodels_release_metatypes.json: illegal value .json 文件为空文件0字节&#xff0c;加 “[]”&#xff0c;不要引号。可以解决这类错误。 Qt编译 Qt for Windows…...

作业练习(python)

第一题&#xff1a; cel eval(input()) fah 9 / 5 * cel 32 print("%.1f" % fah) 第二题&#xff1a; radius, length eval(input()) area radius * radius * 3.14159267 volume area * length print("%.2f" % area) print("%.2f" …...

Wireshark使用相关

1.wireshark如何查看RST包 tcp.flags.reset1 RST表示复位&#xff0c;用来异常的关闭连接&#xff0c;在TCP的设计中它是不可或缺的。发送RST包关闭连接时&#xff0c;不必等缓冲区的包都发出去&#xff08;不像上面的FIN包&#xff09;&#xff0c;直接就丢弃缓存区的包发送R…...

相机标定学习记录

相机标定是计算机视觉和机器视觉领域中的一项基本技术&#xff0c;它的主要目的是通过获取相机的内部参数&#xff08;内参&#xff09;和外部参数&#xff08;外参&#xff09;&#xff0c;以及镜头畸变参数&#xff0c;建立起现实世界中的点与相机成像平面上对应像素点之间准…...

CSS 滚动条样式修改

1、滚动条整体部分 使用 ::-webkit-scrollbar 注意&#xff1a;这个必须要加&#xff0c;不然修改的样式不生效 ::-webkit-scrollbar {width: 10px;//修改滚动条宽度 }2、滚动条中的滑块 使用 ::-webkit-scrollbar-thumb ::-webkit-scrollbar-thumb {border-radius: 8px;b…...

谈谈配置中心?

配置中心可以做集中式的服务配置管理&#xff0c;比如配置一些数据库连接的URL&#xff0c;一些共用的配置且可动态调整的参数。如果不采用集中式的管理&#xff0c;会导致修改起来特别麻烦&#xff0c;一个个的修改特别繁琐。 Nacos Config配置中心中采用的是客户端拉取数据&a…...

人工智能(pytorch)搭建模型25-基于pytorch搭建FPN特征金字塔网络的应用场景,模型结构介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型25-基于pytorch搭建FPN特征金字塔网络的应用场景&#xff0c;模型结构介绍。特征金字塔网络&#xff08;FPN&#xff09;是一种深度学习模型结构&#xff0c;主要应用于目标检测任务中&am…...

JRT业务开发起步

这是一段充满挑战与奋斗的旅程&#xff0c;自第一行Java代码的写下起&#xff0c;便历经重重险阻。从细微的代码行&#xff0c;逐步汇聚成实用的工具类方法&#xff1b;从工具类方法的积累&#xff0c;逐渐构建起功能强大的工具包&#xff1b;再从工具包的整合&#xff0c;最终…...

深度解析:国内主流音视频产品的核心功能与市场表现

前言 当前音视频开发领域呈现出多样化竞争态势&#xff0c;其中声网&#xff08;Agora&#xff09;、即构&#xff08;ZEGO&#xff09;等云通讯企业占据了市场的主导地位。随着技术的持续进步和用户需求的日益多样化&#xff0c;选择音视频服务提供商的标准也越来越个性化&am…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...