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

【Java】内存可见性问题是什么?

文章目录

  • 内存模型
  • 内存可见性
  • 解决方案
    • volatile

内存模型

什么是JAVA 内存模型?

Java Memory Model (JAVA 内存模型)是描述线程之间如何通过内存(memory)来进行交互。 具体说来, JVM中存在一个主存区(Main Memory或Java Heap Memory),对于所有线程进行共享,而每个线程又有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作并非发生在主存区,而是发生在工作内存中,而线程之间是不能直接相互访问,变量在程序中的传递,是依赖主存来完成的。

Java虚拟机规范中定义了Java内存模型.
目的是屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到⼀致的
并发效果.

Java内存模型的抽象示意图如下
在这里插入图片描述

  • 线程之间的共享变量存放在主内存中(Main Memory)
  • 每个线程都有自己的工作内存(Working Memory)
  • 当线程要读取一个共享变量时,会先将变量拷贝到工作内存中,再从工作内存中读取变量
  • 当线程要修改一个共享变量时,也是先修改工作内存中的副本,再同步到主内存中

此时引入了两个问题

  • 为什么要引入这么多的内存
  • 为什么要麻烦的拷贝来拷贝去
  1. 为什么要引入这么多的内存?
    实际上并没有那么多的内存,只是Java规范中的一个术语,是属于抽象的叫法
    所谓的主内存才是硬件角度真正的内存,而工作内存,则是指CPU的寄存器和缓存器

  2. 为什么要麻烦的拷贝来拷贝去?
    因为CPU访问寄存器的速度以及访问缓存器的速度远快于访问内存(快了将近 3-4个数量级,也就是几千倍,上万倍)

比如在代码中,需要连续10次读取某个变量的值,如果10次都从内存中读,那么速度是很慢的。
但如果第一次从内存中读,将结果缓存到寄存器中,那么后面9次的访问就不必访问内存了,效率就提高了

说明白了内存模型,来说说什么是内存可见性

内存可见性

内存可见性Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够立即看到发生的状态变化。

由于线程之间的交互都发生在主内存中,但对于变量的修改又发生在自己的工作内存中,经常会造成读写共享变量的错误,我们也叫可见性错误

可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。

解决方案

我们可以通过同步来保证对象被安全地发布。我们可以使用一种轻量级的volatile变量

volatile

在这里插入图片描述
代码在写入volatile修饰的变量时

  • 改变工作内存中volatile变量副本的值
  • 将改变后的副本的值从工作内存中同步到主内存中

代码在读取volatile修饰的变量时

  • 从主内存中读取最新的值到新的线程的工作内存中

  • 从工作内存中读取volatile变量的副本

    加上volatile虽然使速度变慢了,但是数据变得更准确了。
    
public class test{static class Counter {public int flag = 0;}public static void main(String[] args) {Counter counter = new Counter();Thread t1 = new Thread(() -> {while (counter.flag == 0) {// do nothing}System.out.println("循环结束!");});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);System.out.println("输⼊⼀个整数:");counter.flag = scanner.nextInt();});t1.start();t2.start();}
}//执行代码后
//输入一个非零的值,程序并没有结束

如上t1读的是自己的工作内存中的内容
当t2对flag变量进行修改时,此时t1感知不到t2的变化

如果给flag加上volatile

static class Counter {public volatile int flag = 0;
}
// 执⾏效果
// 当⽤⼾输⼊⾮0值时, t1 线程循环能够⽴即结束.

以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞

相关文章:

【Java】内存可见性问题是什么?

文章目录 内存模型内存可见性解决方案volatile 内存模型 什么是JAVA 内存模型? Java Memory Model (JAVA 内存模型)是描述线程之间如何通过内存(memory)来进行交互。 具体说来, JVM中存在一个主存区(Main Memory或Java Heap Mem…...

Guava里一些比较常用的工具

随着java版本的更新提供了越来越多的语法和工具来简化日常开发,但是我们一般用的比较早的版本所以体验不到。这时就用到了guava这个包。guava提供了很多方便的工具方法,solar框架就依赖了guava的16.0.1版本,这里稍微介绍下。 一、集合工具类…...

在windows系统中【.gz.tar】和【.whl】文件分别应该怎么下载到conda的某个虚拟环境中

在 Windows 系统中&#xff0c;你可以按照以下步骤将 .gz.tar 和 .whl 文件下载到 Conda 的某个虚拟环境中&#xff1a; 激活虚拟环境&#xff1a;打开 Anaconda Prompt 或者命令行窗口&#xff0c;使用以下命令激活你想要安装文件的虚拟环境&#xff1a; conda activate <虚…...

Rust - 数据类型

Rust 是静态编译语言&#xff0c;在编译时必须知道所有变量的类型。 基于使用的值&#xff0c;编译器通常能推断出它的具体类型&#xff0c;但如果可能的类型比较多&#xff0c;例如把String转换为整数的parse方法&#xff0c;就必须添加类型的标注&#xff0c;否则编译会报错…...

基于springboot实现洗衣店订单管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现洗衣店订单管理系统演示 摘要 随着信息互联网信息的飞速发展&#xff0c;无纸化作业变成了一种趋势&#xff0c;针对这个问题开发一个专门适应洗衣店业务新的交流形式的网站。本文介绍了洗衣店订单管理系统的开发全过程。通过分析企业对于洗衣店订单管理系统…...

Java基础知识总结(53)

&#xff08;1&#xff09;集合框架概述 Java集合大致分为List、Set、Map和Queue Collection是一个顶级接口&#xff0c;其子接口有&#xff0c;List、Set、Queue List:有序&#xff08;存放和取出顺序是一致的&#xff09;、有索引、可重复 Set:无序、无索引、不可重复 &…...

196算法之谜在 JSP 中使用内置对象 request 获取 form 表单的文本框 text 提交的数据。

(1&#xff09;编写 inputNumber . jsp &#xff0c;该页面提供一个 form 表单&#xff0c;该 form 表单提供一个文本框 text &#xff0c;用于用户输入一个正整数&#xff0c;用户在 form 表单中输入的数字&#xff0c;单击 submit 提交键将正整数提交给 huiwenNumber . jsp 页…...

初识责任链模式--一起学习吧之数据库

一、定义 责任链模式是一种对象行为型模式&#xff0c;用于处理请求发送者和多个请求处理者之间的耦合问题。在这种模式中&#xff0c;请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时&#xff0c;请求会沿着这条链传递&#xff0c;直到有对象处…...

解决Xshell登录云服务器的免密码和云服务器生成子用户问题

Xshell登录云服务器的免密码问题 前言一、Xshell登录云服务器的免密码操作实践 二、centos创建用户创建用户实操删除用户更改用户密码直接删除子用户 前言 Xshell登录云服务器免密码问题的解决方案通常涉及使用SSH密钥对。用户生成一对密钥&#xff08;公钥和私钥&#xff09;…...

webRtc生产环境实用方法

最近做了几个项目发现多个项目反反复复会出现几个高频的需求&#xff0c; 都依赖于获取系统采集设备和指定设备id获取媒体流&#xff1b;为了不在反复书写总结2个公用方法&#xff1b; 检索当前系统所有可用设备 /*** 检索当前系统所有可用设备* returns {* audioInputOption…...

Java String、StringBuffer

构造方法 通过字符数组构造,结果abc 通过字节数组构造&#xff0c;结果abc //把字符串转化为字节数组 当前代码编译环境为UTF-8&#xff0c;出现异常时&#xff0c;直接抛出异常即可。mainthrows UnsupportedEncodingException 编译环境为UTF-8&#xff0c;但是运用gb2312这个…...

LangChain调用tool集的原理剖析(包懂)

一、需求背景 在聊天场景中&#xff0c;针对用户的问题我们希望把问题逐一分解&#xff0c;每一步用一个工具得到分步答案&#xff0c;然后根据这个中间答案继续思考&#xff0c;再使用下一个工具得到另一个分步答案&#xff0c;直到最终得到想要的结果。 这个场景非常匹配la…...

如何正确使用数字化仪前端信号调理?(一)

一、前言 板卡式的数字转换器和类似测量仪器&#xff0c;比如图1所示的德思特TS-M4i系列&#xff0c;都需要为各种各样的特性信号与内部模数转换器&#xff08;ADC&#xff09;的固定输入范围做匹配。 图1&#xff1a;德思特TS-M4i系列高速数字化仪&#xff0c;包括2或4通道版…...

实验5 流程图和盒图ns图

一、实验目的 通过绘制流程图和盒图&#xff0c;熟练掌握流程图和盒图的基本原理。 能对简单问题进行流程图和盒图的分析&#xff0c;独立地完成流程图和盒图设计。 二、实验项目内容&#xff08;实验题目&#xff09; 1、用Microsoft Visio绘制下列程序的程序流程图。 若…...

[Java、Android面试]_18_详解Handler机制 常见handler面试题(非常重要,非常高频!!)

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&#xff0c;后续会陆续分享出来&#xff0c;感兴趣的朋友可关注收…...

国内开通gpt会员方法

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…...

使用 Meltano 将数据从 Snowflake 导入到 Elasticsearch:开发者之旅

作者&#xff1a;来自 Elastic Dmitrii Burlutskii 在 Elastic 的搜索团队中&#xff0c;我们一直在探索不同的 ETL 工具以及如何利用它们将数据传输到 Elasticsearch&#xff0c;并在传输的数据上实现 AI 助力搜索。今天&#xff0c;我想与大家分享我们与 Meltano 生态系统以及…...

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏,又增加了哔哩哔哩搜索和必应搜索

第24次修改了可删除可持久保存的前端html备忘录:文本编辑框不再隐藏&#xff0c;又增加了哔哩哔哩搜索和必应搜索. <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"…...

二极管分类及用途

二极管分类及用途 通用开关二极管 特点&#xff1a;电流小&#xff0c;工作频率高 选型依据&#xff1a;正向电流、正向压降、功耗&#xff0c;反向最大电压&#xff0c;反向恢复时间&#xff0c;封装等 类型&#xff1a;BAS316 ; IN4148WS 应用电路: 说明&#xff1a;应用…...

文献阅读:Viv:在 web 上多尺度可视化高分辨率多重生物成像数据

文献介绍 「文献题目」 Viv: multiscale visualization of high-resolution multiplexed bioimaging data on the web 「研究团队」 Nils Gehlenborg&#xff08;美国哈佛医学院&#xff09; 「发表时间」 2022-05-11 「发表期刊」 Nature Methods 「影响因子」 47.9 「DOI…...

ChatGLM-6B生产级部署:Supervisor配置文件结构与自定义参数说明

ChatGLM-6B生产级部署&#xff1a;Supervisor配置文件结构与自定义参数说明 1. 引言 在生产环境中部署AI服务时&#xff0c;稳定性是首要考虑的因素。ChatGLM-6B作为一款优秀的开源对话模型&#xff0c;如何确保其7x24小时稳定运行成为了关键问题。本镜像采用了Supervisor进程…...

数据治理平台选型,真正应该看哪几件事

上个月&#xff0c;一位在某制造业集团做数据架构的朋友跟我吐槽&#xff1a;“我们花了半年时间选型&#xff0c;最后上线的产品&#xff0c;管元数据的归元数据&#xff0c;管质量的归质量&#xff0c;两个系统之间打不通&#xff0c;数据血缘断在半路上。现在每次出了数据问…...

CYBER-VISION零号协议Transformer原理与应用实战

CYBER-VISION零号协议Transformer原理与应用实战 如果你对AI大模型背后的“发动机”感到好奇&#xff0c;想知道为什么现在的模型能理解上下文、生成连贯的文本&#xff0c;甚至看懂图片&#xff0c;那么“Transformer”就是你绕不开的核心。它不像过去那些依赖顺序处理的模型…...

Suricata在CentOS7上的性能优化:如何配置网卡混杂模式与端口聚合

Suricata在CentOS7上的性能优化&#xff1a;网卡混杂模式与端口聚合实战指南 当企业网络流量突破千兆级别时&#xff0c;传统单网卡监控方案往往力不从心。我曾为某金融客户部署Suricata时&#xff0c;单台服务器每天要处理超过2TB的流量数据&#xff0c;正是通过下文介绍的网卡…...

避免踩坑:Unity中Resources.LoadAll的正确使用姿势(含multiple模式Sprite处理)

Unity资源加载进阶&#xff1a;Resources.LoadAll与Sprite图集高效处理指南 在Unity开发中&#xff0c;资源加载是每个项目都无法绕开的核心环节。特别是当处理包含多张小图的Sprite图集时&#xff0c;很多开发者会陷入性能陷阱和功能误区。本文将深入剖析Resources.LoadAll的正…...

PHP开发者必看:如何在本地环境快速搭建gRPC和Protobuf开发环境

PHP开发者必看&#xff1a;如何在本地环境快速搭建gRPC和Protobuf开发环境 作为一名长期与PHP打交道的开发者&#xff0c;我深刻理解在微服务架构盛行的当下&#xff0c;掌握gRPC和Protobuf技术栈的重要性。记得第一次尝试在本地搭建环境时&#xff0c;光是版本兼容问题就耗费了…...

Jieba分词实战:5分钟搞定中文文本词频统计(附完整代码)

Jieba分词实战&#xff1a;5分钟搞定中文文本词频统计&#xff08;附完整代码&#xff09; 中文文本处理是自然语言处理&#xff08;NLP&#xff09;的基础环节&#xff0c;而分词则是中文文本处理的第一步。不同于英文等空格分隔的语言&#xff0c;中文文本需要专门的工具进行…...

注意力缺陷是什么?主要有哪几种症状及专注力训练方法?

注意力缺陷病因及其对儿童发展的影响分析 注意力缺陷&#xff08;ADHD&#xff09;的病因较为复杂&#xff0c;主要涉及遗传、环境和生物因素。研究表明&#xff0c;遗传因素在儿童注意力缺陷中起着重要作用&#xff0c;有些家族中更容易出现多动症状。与此同时&#xff0c;环境…...

永磁同步电机全速域无位置传感器控制策略仿真研究:高频注入与改进滑膜控制方法应用

40、永磁同步电机全速域无位置传感器控制仿真&#xff08;仿真代码参考文献说明文档&#xff09; 主要内容&#xff1a; 采用高频注入改进滑膜控制方法&#xff0c;PMSM矢量控制仿真 [1]零低速域&#xff0c;采用无数字滤波器高频方波注入法&#xff0c;减少滤波的相位影响&…...

全向轮底盘运动控制:嵌入式PID与逆运动学实现

1. 全向轮底盘控制库&#xff08;omni_wheel&#xff09;技术解析与工程实践1.1 项目背景与工程定位omni_wheel是为B团队自主移动机器人开发的底层运动控制模块&#xff0c;最初版本发布于2018年7月10日。从其原始README描述“PIDかけて一方向に進むだけのプログラムでござんす…...