当前位置: 首页 > 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…...

【SQL SERVER】定时任务

oracle是定时JOB&#xff0c;sqlserver是创建作业&#xff0c;通过sqlserver代理实现 先看SQL SERVER代理得服务有没有开 选择计算机右键——>管理——>服务与应用程序——>服务——>SQL server 代理 然后把SQL server 代理&#xff08;MSSQLSERVER&#xff09;启…...

MyBatis-Plus学习笔记(无脑cv即可)

1.MyBatis-Plus 1.1特性 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑损耗小&#xff1a;启动即会自动注入基本 CURD&#xff0c;性能基本无损耗&#xff0c;直接面向对象操作强大的 CRUD 操作&#xff1a;内置通用 M…...

【VUE】watch 监听失效

如果你遇见了这个问题&#xff0c;那么尝试在 watch 函数中设置 { deep: true } 选项。这告诉 Vue 监听对象或数组内部的变化&#xff0c;就像下面这样&#xff1a; watch(()>chatStore.dataSources,(oldValue, newValue)>{// 监听执行逻辑 }, { deep: true })嗯&#x…...

python的异常处理批量执行网络设备的巡检命令

前言 在网络设备数量超过千台甚至上万台的大型企业网中&#xff0c;难免会遇到某些设备的管理IP地址不通&#xff0c;SSH连接失败的情况&#xff0c;设备数量越多&#xff0c;这种情况发生的概率越高。 这个时候如果你想用python批量配置所有的设备&#xff0c;就一定要注意这…...

react native 环境准备

一、必备安装 1、安装node 注意 Node 的版本应大于等于 16&#xff0c;安装完 Node 后建议设置 npm 镜像&#xff08;淘宝源&#xff09;以加速后面的过程&#xff08;或使用科学上网工具&#xff09;。 node下载地址&#xff1a;Download | Node.js设置淘宝源 npm config s…...

PGSQL(PostgreSQL)数据库安装教程

安装包下载 下载地址 下载后点击exe安装包 设置的data存储路径 设置密码 设置端口 安装完毕&#xff0c;配置PGSQL的ip远程连接&#xff0c;pg_hba.conf&#xff0c;postgresql.conf&#xff0c;需要更改这两个文件 pg_hba.conf 最后增加一行 host all all …...

识别和修复网站上损坏链接的最佳实践

如果您有一个网站&#xff0c;我们知道您花了很多时间在它上面&#xff0c;以使其成为最好的资源。如果你的链接不起作用&#xff0c;你的努力可能是徒劳的。您网站上的断开链接可能会以两种方式损害您的业务&#xff1a; 它们对企业来说是可怕的&#xff0c;因为当消费者点击…...

使用Navicat连接MySQL出现的一些错误

目录 一、错误一&#xff1a;防火墙未关闭 二、错误二&#xff1a;安全组问题 三、错误三&#xff1a;MySQL密码的加密方式 四、错误四&#xff1a;修改my.cnf配置文件 一、错误一&#xff1a;防火墙未关闭 #查看防火墙状态 firewall-cmd --state#关闭防…...

4G基站BBU、RRU、核心网设备

目录 前言 基站 核心网 信号传输 前言 移动运营商在建设4G基站的时候&#xff0c;除了建设一座铁塔之外&#xff0c;更重要的是建设搭载铁塔之上的移动通信设备&#xff0c;这篇博客主要介绍BBU&#xff0c;RRU以及机房的核心网等设备。 基站 一个基站有BBU&#xff0c;…...

iphone/安卓手机如何使用burp抓包

iphone 1. 电脑 ipconfig /all 获取电脑网卡ip&#xff1a; 192.168.31.10 2. 电脑burp上面打开设置&#xff0c;proxy&#xff0c;增加一条 192.168.31.10:8080 3. 4. 手机进入设置 -> Wi-Fi -> 找到HTTP代理选项&#xff0c;选择手动&#xff0c;192.168.31.10:8080 …...