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

Java多线程基石—内存模型

 Java Memory Model Java内存模型(JMM),定义了线程如何与内存交互及线程间的可见性、有序性和原子性。

JMM屏蔽了各种硬件和操作系统的访问差异,保证Java程序在各种平台下对内存的访问都能保证一致效果。

1 JMM

可见性

一个线程对共享变量的修改,其他线程能立即感知。

原子性

操作不可中断,要么全部执行成功,要不完全不执行。

有序性

代码执行顺序与代码编写顺序一致,避免因指令重排带来的问题。

表 JMM的核心目标

1.1 内存结构

主内存

所有线程共享的内存区域,存储共享变量的原始值。

工作内存

每个线程私有的内存区域,保存该线程使用的共享变量副本。

表 JMM的内存结构

类型

作用域

介绍

lock

主内存

锁定,把一个变量标识为线程独占状态。

unlock

主内存

解锁,把一个处于锁定状态的变量释放。

read

主内存

读取,把一个变量的值从主内存传输到工作内存中。

load

工作内存

加载,把read操作的变量值保存到工作内存的变量副本中。

use

工作内存

使用,把工作内存中的变量值传输给执行引擎。

assign

工作内存

赋值,执行引擎的值存放到工作内存的变量副本中。

store

工作内存

存储,把一个工作内存变量副本的值传送到主内存中。

write

主内存

写入,把store操作的变量值保存到主内存的变量中。

表 JMM的8种内存交互行为

2 指令重排

编译器和处理器为了优化程序性能而对指令执行顺序进行重新排列的一种机制。

2.1 三个层级的指令重排

在保证单线程执行结果不变的前提下,指令重排序会发生在三个层级:

1、编译器重排序

Java编译器(javac、JIT)在生成字节码时,会调整无关指令顺序来提高寄存器利用率或减少指令缓存未命中。

2、处理器指令级并行重排序

CPU通过乱序执行和指令级并行动态调整指令执行顺序,来充分利用流水线资源。

3、内存系统重排序

由于CPU缓存、写缓冲区和缓存一致性协议(如MESI)的存在,可能会对指令重排。

2.2 指令重排序的约束

指令重排序在单线程环境下不会影响程序逻辑,但在多线程环境下可能会导致可见性、原子性和有序性问题。

2.2.1 数据依赖性约束

写后读

Read After Write,RAW。

例子: int a = 1; int b = a; // b依赖a的值 RAW

写后写

Write After Write,WAW。主要是防止多线程环境下出问题。

例子:int a =1; a =2; // 第二次写不能排到第一次写之前 WAW

读后写

Write After Read,WAR。

例子:int b = a; a = 3;

表 数据依赖类型

2.2.2 happens-before 规则

单程序顺序规则

单线程内代码的书写顺序决定操作顺序。

锁规则

对一个锁的解锁happens-before 后续对这个锁的加锁动作。

作用:确保锁释放前的修改对下一个锁持有者可见。

volatile规则

对一个volatile变量的写操作happens-before后续对这个变量的读操作。

作用:确保对volatile变量的修改对所有线程立即可见。

线程启动规则

线程的start()方法调用happens-before 该线程内的所有操作。

作用:确保父线程在启动子线程前的修改对子线程可见。

线程终止规则

线程中所有操作happens-before其他线程检测到该线程已终止。

作用:确保子线程的修改在join()后对父线程可见。

中断规则

对线程interrupt()方法调用happens-before被中断线程检测到中断事件。

对象终结规则

对象的构造函数执行结束happens-before它的finalize()方法被调用。

传递性

如果操作A happens-before操作B,且操作B happens-before操作C,则操作A happens-before 操作C。

表 happens-before 规则

happens-before 保障了可见性:如操作A happens-before 操作B,则A对共享变量的修改对B可见;

2.2.3 内存屏障

是用来禁止特定类型指令重排序的处理器指令,确保内存操作的可见性。

LoadLoad

禁止该屏障前的读操作与屏障后的读操作重排序。

StoreStore

禁止该屏障前的写操作与屏障后的写操作重排序。

LoadStore

禁止该屏障前的读操作与屏障后的写操作重排序。

StoreLoad

禁止该屏障前的写操作与屏障后的读操作重排序。(开销最大)

表 内存屏障类型

相关文章:

Java多线程基石—内存模型

Java Memory Model Java内存模型(JMM),定义了线程如何与内存交互及线程间的可见性、有序性和原子性。 JMM屏蔽了各种硬件和操作系统的访问差异,保证Java程序在各种平台下对内存的访问都能保证一致效果。 1 JMM 可见性 一个线程…...

ArcGIS助力水文分析:数据处理、地图制作与流域特征提取

在水文水环境保护中,对于信息的采集、处理和分析是关键步骤。水文水环境及其相关数据均具有空间分布特征,传统的方法难以发挥作用。地理信息系统(GIS)强大的空间数据管理和分析功能,在空间信息处理上有独到的优势&…...

从以太网 II 到 VLAN 和 Jumbo Frame:数据帧格式解读

以太网数据帧是计算机网络通信的基本单位,在不同的应用场景中,它的格式有所不同。根据协议标准和用途,以太网数据帧主要包括以太网 II 帧、IEEE 802.3 帧、IEEE 802.1Q VLAN 帧等七种主要类型。为了更好地理解以太网的通信机制,我…...

X86 RouterOS 7.18 设置笔记六:端口映射(IPv4、IPv6)及回流问题

X86 j4125 4网口小主机折腾笔记五:PVE安装ROS RouterOS X86 RouterOS 7.18 设置笔记一:基础设置 X86 RouterOS 7.18 设置笔记二:网络基础设置(IPV4) X86 RouterOS 7.18 设置笔记三:防火墙设置(IPV4) X86 RouterOS 7.18 设置笔记四…...

将 IPoIB 驱动修改为仅使用 RC 模式

摘要 本文档详细介绍了将 Linux 内核中的 IPoIB(IP over InfiniBand)驱动修改为仅使用 RC(Reliable Connection,可靠连接)模式,并移除所有与 TCP/IP 和以太网相关部分的方法。通过这些修改,可以优化 IPoIB 驱动以适应特定的高性能计算场景,提高数据传输的可靠性和效率…...

热修复框架Tinker与Robust原理剖析

热修复框架Tinker与Robust原理剖析 一、热修复技术概述 1.1 什么是热修复 热修复(Hot Fix)是Android平台上的一种动态修复机制,它允许应用在不重新发布版本的情况下,动态修复线上bug。这种技术对于快速修复线上问题、降低用户流…...

69.Harmonyos NEXT图片预览组件应用实践(二):电商、内容与办公场景

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! Harmonyos NEXT图片预览组件应用实践(二):电商、内容与办公场景 文章目录 Harmonyos NEXT图片预览组件应用实践…...

C题库-判断水仙花数

【数据判断】 问题1&#xff1a;判断水仙花数&#xff0c;水仙花数是指一个三位数&#xff0c;其各位数字的立方和等于该数本身。 方法一&#xff1a; #include<stdio.h>int main(void){int num,Bit,Ten,Hundred;printf("Input a number:");scanf("%d&q…...

31.Harmonyos Next仿uv-ui 组件NumberBox 步进器组件异步操作处理

Harmonyos Next仿uv-ui 组件NumberBox 步进器组件异步操作处理 文章目录 Harmonyos Next仿uv-ui 组件NumberBox 步进器组件异步操作处理1. 组件介绍2. 效果展示3. 异步操作处理3.1 异步初始化3.2 异步值更新 4. 完整示例代码5. 知识点讲解5.1 异步操作基础5.2 异步操作中的状态…...

MIPI电平标准详解

一、MIPI电平的定义与核心特性 MIPI&#xff08;Mobile Industry Processor Interface&#xff09; 是由 MIPI联盟 制定的移动设备接口标准&#xff0c;涵盖摄像头&#xff08;CSI&#xff09;、显示屏&#xff08;DSI&#xff09;、射频&#xff08;RFFE&#xff09;等多个领…...

使用位运算实现加法、减法、乘法和除法

使用位运算实现加法、减法、乘法和除法是一个经典的计算机科学问题。位运算通常用于低级程序设计和性能优化中&#xff0c;以下是如何用位运算实现这些基本数学运算。 加法 加法可以通过以下步骤实现&#xff1a; def add(a, b):while b ! 0:# 使用异或得到不考虑进位的加法…...

深入解析Go语言Channel:源码剖析与并发读写机制

文章目录 Channel的内部结构Channel的创建过程有缓冲Channel的并发读写机制同时读写的可能性发送操作的实现接收操作的实现 并发读写的核心机制解析互斥锁保护环形缓冲区等待队列直接传递优化Goroutine调度 实例分析&#xff1a;有缓冲Channel的并发读写性能优化与最佳实践缓冲…...

mac安装python没有环境变量怎么办?zsh: command not found: python

在mac电脑上,下载Python安装包进行安装之后,在终端中,输入python提示: zsh: command not found: python 一、原因分析 首先,这个问题不是因为python没有安装成功的原因,是因为python安装的时候,没有为我们添加环境变量导致的,所以我们只需要,在.zshrc配置文件中加上环…...

使用DeepSeek制作可视化图表和流程图

用DeepSeek来制作可视化图表&#xff0c;搭配python、mermaid、html来实现可视化&#xff0c;我已经测试过好几种场景&#xff0c;都能实现自动化的代码生成&#xff0c;效果还是不错的&#xff0c;流程如下。 统计图表 &#xff08;搭配Matplotlib来做&#xff09; Python中的…...

jmeter-sample

jmeter-sample http request:接口测试常用请求参数ParametersBody DataFiles Upload jdbc request配置JDBC Connection Configuration创建JDBC Requst请求 http request:接口测试常用 请求参数 Parameters 常见于get请求&#xff0c;与拼在接口后面是一样的效果&#xff1a;如…...

C++之文字修仙小游戏

1 效果 1.1 截图 游戏运行&#xff1a; 存档&#xff1a; 1.2 游玩警告 注意&#xff01;不要修改装备概率&#xff0c;装备的概率都是凑好的数字。如果想要速升&#xff0c;修改灵石数量 2 代码 2.1 代码大纲 1. 游戏框架与初始化 控制台操作&#xff1a;通过 gotoxy() …...

C++ vector 核心知识:常用操作与示例详解

在C编程中&#xff0c;vector 是标准模板库&#xff08;STL&#xff09;中最常用的容器之一。它以其动态数组的特性、高效的尾部操作和便捷的随机访问能力&#xff0c;成为处理动态数据的首选工具。无论是初学者还是经验丰富的开发者&#xff0c;掌握 vector 的使用方法和性能优…...

结构型模式之适配器模式:让不兼容的接口兼容

在软件开发中&#xff0c;经常会遇到这样一种情况&#xff1a;系统的不同部分需要进行交互&#xff0c;但由于接口不兼容&#xff0c;导致无法直接使用。这时&#xff0c;适配器模式&#xff08;Adapter Pattern&#xff09;就能派上用场。适配器模式是设计模式中的结构型模式&…...

从零开始探索C++游戏开发:性能、控制与无限可能

一、为何选择C开发游戏&#xff1f; 在虚幻引擎5渲染的次世代画面背后&#xff0c;在《巫师3》的庞大开放世界中&#xff0c;在《毁灭战士》的丝滑60帧战斗里&#xff0c;C始终扮演着核心技术角色。这门诞生于1983年的语言&#xff0c;至今仍占据着游戏引擎开发语言使用率榜首…...

使用mvn archetype命令,构建自定义springboot archetype脚手架创建工程的方法

使用mvn archetype命令&#xff0c;构建自定义springboot archetype脚手架创建工程的方法 文章目录 使用mvn archetype命令&#xff0c;构建自定义springboot archetype脚手架创建工程的方法一、背景二、环境三、archetype插件配置四、基于项目构建脚手架archetype包五、检查模…...

Hutool RedisDS:Java开发中的Redis极简集成与高阶应用

在Java开发中&#xff0c;Redis作为高性能内存数据库&#xff0c;广泛应用于缓存、分布式锁等场景。然而原生的客户端操作涉及连接管理、序列化等繁琐细节。Hutool工具包提供的RedisDS模块&#xff0c;通过高度封装显著简化了这一过程。本文从实战角度解析其核心特性与使用技巧…...

MacOS 15.3.1 安装 GPG 提示Error: unknown or unsupported macOS version: :dunno

目录 1. 问题锁定 2. 更新 Homebrew 3. 切换到新的 Homebrew 源 4. 安装 GPG 5. 检查 macOS 版本兼容性 6. 使用 MacPorts 或其他包管理器 7. 创建密钥&#xff08;生成 GPG 签名&#xff09; 往期推荐 1. 问题锁定 通常是因为你的 Homebrew 版本较旧&#xff0c;或者你…...

Sqlmap注入工具简单解释

安装 1. 安装 Python SQLMap 是基于 Python 开发的&#xff0c;所以要先安装 Python 环境。建议安装 Python 3.9 或更高版本&#xff0c;可从 Python 官方网站 下载对应操作系统的安装包&#xff0c;然后按照安装向导完成安装。 2. 获取 SQLMap 可以从 SQLMap 的官方 GitHu…...

硬件驱动——51单片机:独立按键、中断、定时器/计数器

目录 一、独立按键 1.原理 2.封装函数 3.按键控制点灯 数码管 二、中断 1.原理 2.步骤 3.中断寄存器IE 4.控制寄存器TCON 5.打开外部中断0和1 三、定时器/计数器 1.原理 2.控制寄存器TCON 3.工作模式寄存器TMOD 4.按键控制频率的动态闪烁 一、独立按键 1…...

语文-文言文

文章目录 短歌行归园田居梦游天姥吟留别 / 别东鲁诸公 学习文言文&#xff0c;适当个人分析&#xff1b; 短歌行 曹操 对酒当歌&#xff0c;人生几何&#xff08;主题&#xff0c;人生很短暂&#xff09;&#xff1b; 譬如朝露&#xff0c;去日苦多&#xff08;比喻&#xff0c…...

P1259 黑白棋子的移动【java】【AC代码】

有 2n 个棋子排成一行&#xff0c;开始为位置白子全部在左边&#xff0c;黑子全部在右边&#xff0c;如下图为 n5 的情况&#xff1a; 移动棋子的规则是&#xff1a;每次必须同时移动相邻的两个棋子&#xff0c;颜色不限&#xff0c;可以左移也可以右移到空位上去&#xff0c;但…...

【极光 Orbit·STC8AH】04. 深度探索 GPIO 底层逻辑

【极光 OrbitSTC8A&H】04. 深度探索 GPIO 底层逻辑 引言&#xff1a;当代码遇见硬件 上周我看着学生调试的工控产品&#xff0c;他们困惑地盯着自己编写的代码&#xff1a;“老师&#xff0c;这段C语言明明在PC上跑得没问题啊&#xff01;” &#xff0c;让我想起自己初学…...

67.Harmonyos NEXT 图片预览组件之性能优化策略

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; Harmonyos NEXT 图片预览组件之性能优化策略 文章目录 Harmonyos NEXT 图片预览组件之性能优化策略效果预览一、性能优化概述1. 性能优化的关键指标…...

uni-app+SpringBoot: 前端传参,后端如何接收参数

做项目中的一些小经验&#xff0c;方便后续 &#xff08;1&#xff09;前端代码中&#xff0c;请求的 URL 是通过查询参数&#xff08;?id${articleId}&#xff09;传递的 后端接口&#xff1a; GetMapping("/knowledgeDetail") public Result getKnowledgeByid(R…...

【Vue.js】

一、简介 1、概述 官网GitHub - Vuejs Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 Vue.js作为一个渐进式框架&#xff0c;其设计理…...