聊聊Java的内存模型

聊聊Java的内存模型

目录

1、Java的内存模型(JMM)介绍

JMM核心定义和作用

JVM和JMM的区别

2.JMM核心概念

主内存和工作内存

内存间的交互操作

内存三大特性

原子性

可见性

有序性

3.Happens-Before规则

Happens-Before规则介绍

六大happens-before规则

4.volatile关键字

5.JMM的常见误区

volatile无法保证原子性

指令重排序的陷阱


1、Java的内存模型(JMM)介绍

JMM核心定义和作用

Java内存模型(Java Memory Model,JMM)是Java虚拟机规范中定义的一种抽象概念,它规定了多线程环境下,线程如何与内存进行交互。

JMM的核心作用:

  • 定义程序中各个变量的访问规则
  • 确保多线程程序的可见性有序性原子性
  • 屏蔽不同硬件平台和操作系统的内存访问差异

JVM和JMM的区别

说到JMM,我们不得不提到它经常被人所搞混淆的另一个概念JVM,我们用一张表来直观表现出它们的区别。

JVM内存结构

Java内存模型
核心关注点数据存储的物理/逻辑分区线程与内存的交互规则
内容堆、栈、方法区等内存区域主内存、工作内存抽象概念
目的内存分配与管理多线程内存可见性控制


2.JMM核心概念

主内存和工作内存

  • 主内存:所有线程共享的内存区域,存储所有实例字段、静态字段和数组元素
  • 工作内存:每个线程私有的内存空间,存储线程使用变量的副本

当某个线程需要使用到内存中的变量时,他会先从主内存中复制一份该变量的副本到自己的工作内存当中,使用完后再将该变量写入主内存的共享内存中。

内存间的交互操作

  • lock/unlock:作用于主内存,标识变量为线程独占状态
  • read/load:从主内存读取变量到工作内存
  • use/assign:工作内存中使用和赋值操作
  • store/write:将工作内存变量写回主内存

内存三大特性

原子性

核心概念:原子性指一个操作或一系列操作要么全部执行成功,要么全部不执行,不会出现执行到一半的状态。

// 原子操作示例 int x = 10; // 原子的:一次性赋值 boolean flag = true; // 原子的 // 非原子操作示例 int i = 0; i++; // 非原子的,实际包含3个步骤: // 1.读取i的值到寄存器 // 2.寄存器值加1 // 3.写回内存 

可见性

核心概念:可见性指当一个线程修改了共享变量的值,其他线程能够立即看到修改后的值。

 private boolean running = true; // 主内存中的变量 public void run() { while (running) { // 工作内存中的副本 // 看不到running被改为false } } public void stop() { running = false; // 修改主内存,但工作内存可能没更新 }

有序性

核心概念:有序性指程序执行的顺序按照代码的先后顺序执行。但在多线程或优化环境下,指令可能被重排序

重排序原因:

  • 编译器优化重排序
  • 处理器指令级并行重排序
  • 内存系统重排序
 private int x = 0; private boolean flag = false; // 线程1执行 public void writer() { x = 42; // 1 flag = true; // 2 可能被重排到1之前! } // 线程2执行 public void reader() { if (flag) { // 3 System.out.println(x); // 可能输出0而不是42! } }

3.Happens-Before规则

Happens-Before规则介绍

Happens-Before是JMM的核心概念,它定义了两个操作之间的偏序关系

  • 如果操作A happens-before​ 操作B
  • 那么A的所有写操作对B的读操作都是可见

有点难看懂,我们用一个简单的例子就能快速理解

// 核心:happens-before ≠ 时间先后 int x = 0; int y = 0; // 时间上:先执行1,后执行2 x = 1; // 1 y = x + 1; // 2 // 逻辑上:1 happens-before 2 // 所以2一定能看到1写入的值

A happens-before B 翻译过来就是:A对B可见。

六大happens-before规则

  • 程序次序规则:线程内,按照程序代码顺序,前面的操作happens-before后面的操作。
  • 监视器锁规则:对一个锁的解锁操作happens-before后续对这个锁的加锁操作。
  • volatile变量规则:对一个volatile变量的操作happens-before后续对这个变量的操作。
  • 线程启动规则:Thread对象的start()方法调用happens-before该线程的每一个动作
  • 线程终止规则:线程中的所有操作happens-before其他线程检测到该线程已经终止
  • 传递性规则:如果A happens-before B,且B happens-before C,那么A happens-before C

4.volatile关键字

核心概述:volatile是一个重要的关键字,用于告知编译器某个变量的值可能会被程序外部的因素意外修改,从而避免编译器对该变量进行优化。它的主要作用是确保每次访问变量时都从内存中读取最新的值,而不是使用寄存器中的缓存值。

volatile提供了两大保证:

  • 可见性:修改立即对所有线程可见
  • 有序性:禁止指令重排序
 private volatile boolean flag = false; private int count = 0; public void writer() { count = 42; // 普通写操作 flag = true; // volatile写操作 } public void reader() { if (flag) { // volatile读操作 // 这里一定能看到count=42 System.out.println(count); } }

5.JMM的常见误区

volatile无法保证原子性

volatile可以保证可见性和有序性,但和synchronized不一样,不能保证原子性

// 错误:以为volatile能保证原子性 volatile int count = 0; count++; // 非原子操作 // 正确:使用原子类或同步 AtomicInteger atomicCount = new AtomicInteger(0); atomicCount.incrementAndGet();

指令重排序的陷阱

// 可能由于重排序导致问题 int a = 0; boolean flag = false; // 线程1 a = 1; // 1 flag = true; // 2 可能重排到1之前 // 线程2 if (flag) { System.out.println(a); // 可能输出0 }

此时我们需对flag使用volatile关键字修饰即可保证在a赋值后再执行flag=true操作。


制作不易,如果对你有帮助请点赞,评论,收藏,感谢大家的支持

Read more

OpenClaw多智能体路由实战:飞书多机器人配置指南

文章目录 * 飞书重新安装问题 * 批量增加机器人 * 缺点 * 多个飞书机器人名称包含大小写的问题 * 多个Agent名称包含大小写的问题 目前我已经完成了OpenClaw的基本安装,但是在对话框只有一个,机器人也只绑定到主会话,一次只能处理一个消息。很多时候我在聊天窗口,说A任务,然后做了一半,又发了关于B任务的指令。一是每次发完消息,如果OpenClaw还在处理,剩下的消息要么进入队列、要么看不到(实际还在队列)。两个任务切来切去,感觉体验很不好。 要彻底解决这个问题,实现网上演示的那种对各Agent、每个对话机器人对应一个Agent,就需要用到多智能体路由技术。 实现的步骤如下: * 在飞书创建一个新的机器人 * 通过控制台创建新的智能体 * 按照指引将飞书配置上去 * 根据需要创建多个Agent和机器人,并对应配置上去(略) 飞书重新安装问题 明明我已经安装好了飞书,系统还是会提示我安装,否则就跳过了添加飞书这步。应该是系统Bug。这次安装的飞书位置在~/.openclaw/extensions/feishu,其实和~/.npm-globa

By Ne0inhk

Vitis AI推理加速实战:从零实现FPGA部署完整指南

从模型到硬件:Vitis AI 实战部署指南,让 FPGA 真正跑起深度学习 你有没有遇到过这样的场景?训练好的 PyTorch 模型准确率高达95%,信心满满地准备上板推理——结果在嵌入式 CPU 上一跑, 一张图要300毫秒 ,帧率不到4 FPS。别说实时检测了,连基本交互都卡顿。 这正是我在做工业缺陷检测项目时踩过的坑。后来我们换了一条路:把模型交给 FPGA + Vitis AI ,最终实现 每张图仅需12ms 的惊人加速。整个系统功耗还从5W降到2.5W,彻底告别风扇散热。 今天我就带你走一遍这条“少有人走却极高效”的路径—— 如何用 Xilinx 的 Vitis AI 工具链,把一个标准 PyTorch/TensorFlow 模型真正部署到 Zynq 或 Versal 芯片上,实现低延迟、

By Ne0inhk
Spatial Joy 2025 全球 AR&AI 赛事:开发者要的资源、玩法、避坑攻略都在这

Spatial Joy 2025 全球 AR&AI 赛事:开发者要的资源、玩法、避坑攻略都在这

Spatial Joy 2025 全球 AR&AI 赛事:开发者要的资源、玩法、避坑攻略都在这 * 引言: * 正文: * 一、赛事核心价值:资源、履历、落地全具备 * 1.1 硬核资源支持 * 1.2 行业背书与机遇 * 1.3 低门槛试错 * 二、赛道核心玩法:AI 和 AR 创作方向解析 * 2.1 AI 赛道:拼的是 "空间认知协作" 能力 * 2.1.1 应用示例 * 2.2 AR 赛道:

By Ne0inhk

企业微信外部群“群机器人”主动推送消息实现指南

QiWe开放平台 · 开发者名片                 API驱动企微自动化,让开发更高效         核心能力:企微二次开发服务 | 多语言接入 | 免Root授权         官方站点:https://www.qiweapi.com(功能全景)         开发文档:https://doc.qiweapi.com(开发指南)         团队定位:专注企微API生态的技术服务团队        对接通道:搜「QiWe 开放平台」联系客服         核心理念:合规赋能,让企微开发更简单、更高效 在企业微信的生态开发中,针对外部群(包含微信用户的群聊)进行自动化消息推送,最稳健且合规的方式是利用群机器人(Webhook)。本文将从技术逻辑、核心步骤及注意事项三个维度,分享如何实现这一功能。 一、 实现逻辑简述 企业微信外部群机器人主要通过一个唯一的 Webhook 地址 接收标准的 HTTP POST 请求。开发者只需将构造好的

By Ne0inhk