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

<JavaEE> volatile关键字 -- 保证内存可见性、禁止指令重排序

目录

一、内存可见性

1.1 Java内存模型(JMM)

1.2 内存可见性演示

二、指令重排序

三、关键字 volatile 


一、内存可见性

1.1 Java内存模型(JMM)

1)什么是Java内存模型(JMM)?
Java内存模型即Java Memory Model,简称JMM。用于屏蔽各种硬件和操作系统的内存访问差异,以实现让Java程序在各平台下都能够达到一致的内存访问效果,即实现“跨平台”。
2)JMM中的“主内存”概念和“工作内存”概念
“主内存”硬件中的内存,在JMM中表述为“主内存”,其中存储了线程间的共享变量等数据。
“工作内存”CPU寄存器和缓存等临时存储区,在JMM中表述为“工作内存”,每个线程都有自己的“工作内存”。
3)线程和“主内存”、“工作内存”的关系

当线程需要读取共享变量时,会从“主内存”拷贝至“工作内存”,再从“工作内存”读取。

当线程需要修改共享变量时,会先修改“工作内存”中的数据副本,再将数据同步回“主内存”。

线程运行中,数据的交互是频繁且持续的,而CPU访问自身寄存器和高速缓存的速度远高于访问内存的速度。

因此,采用频繁与“工作内存”交互、需要时再与“主内存”交互的工作策略,有利于提高运行效率,是编译器优化的方式之一

1.2 内存可见性演示

什么是内存可见性?

内存可见性是指,线程对共享变量值的修改,能否被其他线程及时察觉。

如果一个线程修改了共享变量值,但没有及时写回内存中,导致其他线程无法获得已修改的正确数据,这就被认为出现了线程安全问题。

内存可见性是导致线程不安全的原因之一。

代码演示内存不可见导致线程不安全:

public class Volatile_Demo0 {//有一个共享变量flag,注意该变量没有被 volatile 修饰;public static int flag = 0;public static void main(String[] args) throws InterruptedException {//创建一个线程,线程中当flag为0时,一直循环判断;Thread t = new Thread(()->{while (flag == 0){}});//启动线程;System.out.println("run开始");t.start();//让main线程休眠两秒后,将flag的值改为1;Thread.sleep(2000);flag = 1;//让main线程等待t线程结束;t.join();System.out.println("run结束");}
}//运行结果:
run开始
...程序一直在执行,没有打印“run结束”。
出现了线程安全问题。

上述代码问题分析:

程序无法结束的原因是什么?

根据代码,flag 在线程启动两秒后被改为 1 ,此时 t 线程应该因为跳出 while 循环而执行完毕。

但实际情况却不是这样,t 线程没有结束。

正如上文“线程和‘主内存’、‘工作内存’的关系”中提到的,线程读取共享数据到“工作内存中”,再从“工作内存”读取数据。

所以此时在 t 线程中,参与 while 循环条件判断的 flag ,实际上是一个存储在“工作内存”的 flag 副本。

当 flag 通过另一线程改变值,改变的是“主内存”中的 flag,t 线程并不能察觉。

因此 t 线程无法从 while 循环中跳出并结束。

这就是内存可见性影响线程安全的情况之一。


二、指令重排序

1)什么是指令重排序?

指令重排序是指编译器自动调整原有代码的执行顺序,在保证逻辑不变的前提下,提高程序运行效率。

指令重排序也是编译器优化的方式之一。

2)指令重排序存在什么问题?

指令重排序的前提是“保证逻辑不变”。这一点在单线程环境下较容易判断,但是在多线程环境下,代码复杂程度高,编译器在编译阶段对代码执行效果的判断存在困难。

因此在多线程环境下,代码重排序很容易导致优化后和优化前的逻辑不等价。

图示演示指令重排序可能出现的问题:


三、关键字 volatile 

1)volatile 的作用是什么?
<1>

保证内存可见性。volatile 修饰的变量每次被访问都必须从内存中读取,每次被修改都必须存储到内存中。

<2>禁止指令重排序。volatile 修饰的变量读写操作的相关指令不允许被重排序。
2)内存可见性和指令重排序都是编译器优化,怎么好像都是负作用?

在大部分场景下,编译器优化都能非常优秀的提高程序的运行效率,只是在多线程编程的部分关键代码中,存在线程不安全的风险。

3)volatile 不保证原子性
volatile 和 synchronized 有本质的区别,synchronized 保证原子性,而 volatile 保证的是内存可见性。
4)合理的使用 volatile 关键字

编译器优化就好像一场激烈的风暴,而程序员要做的就是掌控这场风暴,必要时让风暴停一停。

为此,Java 提供了 volatile 关键字供程序员使用。当使用 volatile 关键字时,强制读写内存,禁止指令重排序,程序运行速度变慢,但数据准确性提高,线程变得安全了。

代码演示 volatile 的使用效果,沿用上文“内存可见性演示”中的代码:

public class Volatile_Demo0 {//有一个共享变量flag,注意该变量已经被 volatile 修饰;public volatile static int flag = 0;public static void main(String[] args) throws InterruptedException {//创建一个线程,线程中当flag为0时,一直循环判断;Thread t = new Thread(()->{while (flag == 0){}});//启动线程;System.out.println("run开始");t.start();//让main线程休眠两秒后,将flag的值改为1;Thread.sleep(2000);flag = 1;//让main线程等待t线程结束;t.join();System.out.println("run结束");}
}//运行结果:
run开始
run结束与上文“内存可见性演示”中的代码唯一的不同,就是在共享变量 flag 上,使用了 volatile 进行修饰。
但这次的结果是程序正常执行完毕,证明了 volatile 的作用。

相关文章:

<JavaEE> volatile关键字 -- 保证内存可见性、禁止指令重排序

目录 一、内存可见性 1.1 Java内存模型(JMM) 1.2 内存可见性演示 二、指令重排序 三、关键字 volatile 一、内存可见性 1.1 Java内存模型(JMM) 1&#xff09;什么是Java内存模型&#xff08;JMM&#xff09;&#xff1f;Java内存模型即Java Memory Model&#xff0c;简…...

docker安装mysql8

docker安装mysql8 docker search mysql:8 #搜索可以使用的msyql8的镜像 docker pull mysql:8.0.27 #拉去mysql8的镜像 创建挂载的宿主机目录 mkdir -p /data/mysql/mysql8/conf # 配置文件目录 mkdir -p /data/mysql/mysql8/data # 数据目录 touch /data/mysql/mysql8/conf/my.…...

消息丢失排查方法?

遇到丢消息问题&#xff0c;如果是单聊&#xff0c;群聊&#xff0c;聊天室&#xff0c;系统消息可以在开发者后台北极星自助查询一下消息是否发送成功。根据您实际发送的相关信息&#xff08;发送者、接收者、时间、消息 ID ……&#xff09;看是否可以查到消息 如果消息查不到…...

Linux 匿名页反向映射

1. 何为反向映射 正向映射&#xff1a; 用户进程在申请内存时&#xff0c;内核并不会立刻给其分配物理内存&#xff0c;而是先为其分配一段虚拟地址空间&#xff0c;当进程访问该虚拟地址空间时&#xff0c;触发page fault异常&#xff0c;异常处理流程中会为其分配物理页面&am…...

国内首个农业开源鸿蒙操作系统联合华为正式发布

2023年11月29日&#xff0c;在中国国际供应链促进博览会上&#xff0c;中信农业科技股份有限公司&#xff08;简称“中信农业”&#xff09;与深圳开鸿数字产业发展有限公司&#xff08;简称“深开鸿”&#xff09;以及华为技术有限公司&#xff08;简称“华为”&#xff09;联…...

python HTML文件标题解析问题的挑战

引言 在网络爬虫中&#xff0c;HTML文件标题解析扮演着至关重要的角色。正确地解析HTML文件标题可以帮助爬虫准确地获取所需信息&#xff0c;但是在实际操作中&#xff0c;我们常常会面临一些挑战和问题。本文将探讨在Scrapy中解析HTML文件标题时可能遇到的问题&#xff0c;并…...

AIM: Symmetric Primitive for Shorter Signatures with Stronger Security

目录 笔记后续的研究方向摘要引言贡献 AIM: Symmetric Primitive for Shorter Signatures with Stronger Security CCS 2023 笔记 后续的研究方向 摘要 基于头部MPC&#xff08;MPCitH&#xff09;范式的后量子签名方案最近引起了人们的极大关注&#xff0c;因为它们的安全性…...

【 Go语言使用xorm框架操作数据库】

Go语言使用xorm框架操作数据库 Xorm 是一个简单而强大的Go语言ORM&#xff08;对象关系映射&#xff09;库。它支持自动将结构体映射到数据库表&#xff0c;并提供了一系列便捷的API来执行CRUD&#xff08;创建、读取、更新和删除&#xff09;操作。 安装 Xorm 首先&#xf…...

DouyinAPI接口系列丨Douyin商品详情数据接口丨Douyin视频详情数据接口

抖音商品详情API是抖音开放平台提供的一套API接口&#xff0c;用于获取商品详情信息。通过该API&#xff0c;开发者可以获取到商品的详细信息&#xff0c;包括商品ID、名称、描述、价格、销量、评价等信息。 在使用抖音商品详情API之前&#xff0c;需要先注册并登录抖音开放平…...

旺店通对接中国南方电网,打破跨系统连接,让数据轻易互通成为现实

接入系统&#xff1a;旺店通企业版 旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案&#xff0c;助力零售企业数字化智能化管理升级。为零售电商企业的订单管理及仓储管理提供…...

简介Kadane算法及相关的普通动态规划

简介Kadane算法及相关的普通动态规划 本文详细论述Kadane算法的经典题目&#xff0c;并通过“首先列出动态规划解法&#xff0c;再改为Kadane算法解法”的方式&#xff0c;讲解二者的不同。最后给出一道Kadane算法变体的题目&#xff0c;解法极为简洁优美。 Kadane算法也是一…...

校园教务管理系统

学年论文&#xff08;课程设计&#xff09; 题目&#xff1a; 信息管理系统 校园教务管理系统 摘要&#xff1a;数据库技术是现代信息科学与技术的重要组成部分&#xff0c;是计算机数据处理与信息管理系统的核心&#xff0c;随着计算机技术的发展&#xff0c;数据库技…...

【LeetCode热题100】【双指针】接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] …...

软件工程-(可行性分析、需求分析)

目录 一.可行性研究 1.1定义 1.2项目背景 1.3三方面研究目标系统的可行性 1.3.1技术可行性分析 1.3.2 经济可行性分析 1.3.3 市场可行性分析 1.4. 数据流图 数据字典&#xff08;DD&#xff09; 1.5风险评估 1.6结论与建议 二、需求分析 引言 项目概述 利益相关者分析…...

HuggingFace学习笔记--BitFit高效微调

1--BitFit高效微调 BitFit&#xff0c;全称是 bias-term fine-tuning&#xff0c;其高效微调只去微调带有 bias 的参数&#xff0c;其余参数全部固定&#xff1b; 2--实例代码 from datasets import load_from_disk from transformers import AutoTokenizer, AutoModelForCaus…...

阅读笔记|A Survey of Large Language Models

阅读笔记 模型选择&#xff1a;是否一定要选择参数量巨大的模型&#xff1f;如果需要更好的泛化能力&#xff0c;用于处理非单一的任务&#xff0c;例如对话&#xff0c;则可用选更大的模型&#xff1b;而对于单一明确的任务&#xff0c;则不一定越大越好&#xff0c;参数小一…...

JSP 设置静态文件资源访问路径

这里 我们先在 WEB目录webapp 下创建一个包 叫 static 就用它来存静态资源 然后 我们扔一张图片进去 我们直接这样写 如下图 找到父级目录 然后寻找下面的 static 下的 img.png 运行代码 很明显 它没有找到 这边 我们直接找到 webapp目录下的 WEB-INF目录下的 web.xml 加入…...

【Pytorch】Visualization of Feature Maps(4)——Saliency Maps

学习参考来自 Saliency Maps的原理与简单实现(使用Pytorch实现)https://github.com/wmn7/ML_Practice/tree/master/2019_07_08/Saliency%20Maps Saliency Maps 原理 《Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps》&…...

java第三十课

电商项目&#xff08;前台&#xff09;&#xff1a; 登录接口 注册接口后台&#xff1a; 注册审核&#xff1a;建一个线程类 注意程序中的一个问题。 这里是 5 条记录&#xff0c;2 条记录显示应该是 3 页&#xff0c;实际操作过程 有审核机制&#xff0c;出现了数据记录动态变…...

Scala--2

package scala02object Scala07_typeCast {def main(args: Array[String]): Unit {// TODO 隐式转换// 自动转换val b: Byte 10var i: Int b 10val l: Long b 10 100Lval fl: Float b 10 100L 10.5fval d: Double b 10 100L 10.5f 20.00println(d.getClass…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...