聊聊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

统信 UOS V2500 服务器 | OpenClaw AI Agent 全流程安装部署手册

一、文档概述 1.1 文档目的 本文档详细阐述在统信 UOS 服务器操作系统中安装、部署及初始化配置 OpenClaw 的全流程,为运维人员及开发人员可落地的操作指南,确保 OpenClaw 稳定部署并正常发挥其 AI 助手核心能力。 1.2 OpenClaw 简介 OpenClaw 是一款本地 AI Agent 工具,前身为 Clawdbot,经 moltbot 阶段迭代优化,具备高主动性和强系统底层操作能力。核心功能包括执行 Shell 命令、自动化提交 Git PR、管理数据库,支持对接 Telegram、WhatsApp 等主流通讯应用;其 “Skills” 插件机制可按需扩展功能,默认本地部署模式,兼容 Anthropic、OpenAI

By Ne0inhk
Claude Code Security:AI猎杀代码漏洞时代正式开启

Claude Code Security:AI猎杀代码漏洞时代正式开启

文章目录 * 1、前言 * 2、快速上手:Claude Code Security 怎么用 * 2.1 访问入口与适用范围 * 2.2 两种使用方式 * 2.2.1 方式一:终端命令(所有付费用户) * 2.2.2 方式二:GitHub Actions 集成(自动化 PR 扫描) * 2.3 Dashboard 核心功能一览(企业版) * 3、背景:代码安全为何成了 AI 的下一个战场 * 3.1 软件漏洞:永无止境的噩梦 * 3.2 传统 SAST 工具的三大痛点

By Ne0inhk
告别兼容性烦恼!在Mac Big Sur上使用OpenClaw+OpenCode+OpenSpec实现全自动化AI开发流程

告别兼容性烦恼!在Mac Big Sur上使用OpenClaw+OpenCode+OpenSpec实现全自动化AI开发流程

告别兼容性烦恼!在Mac Big Sur上使用OpenClaw+OpenCode+OpenSpec实现全自动化AI开发流程 🚀 引言:AI 自动化开发三件套 如果你关注 AI 辅助编程,最近一定听说过这三个工具: * OpenClaw:个人 AI 助手框架,擅长调度任务、管理记忆、调用工具,是整个流程的“指挥官”。 * OpenCode:AI 编程代理,能够深入理解代码库、自动修改代码、运行测试,是真正的“一线工程师”。 * OpenSpec:规范驱动框架,将模糊的需求转化为结构化的任务清单(tasks.md),是项目的“施工蓝图”。 三者结合,可以构建一个从需求分析到代码落地的全自动化开发流水线。你只需要提出想法,AI 就能自主完成代码编写、调试和提交。 然而,很多开发者(包括我)还在使用 macOS 11 Big

By Ne0inhk
黄仁勋力荐:OpenClaw不止是下一个ChatGPT,更是AI“动手时代”的破局者

黄仁勋力荐:OpenClaw不止是下一个ChatGPT,更是AI“动手时代”的破局者

在2026年GTC大会上,英伟达创始人兼CEO黄仁勋抛出了一个振聋发聩的判断:“OpenClaw绝对是下一个ChatGPT”。 这一评价并非夸大其词,而是精准点出了AI产业的核心演进方向——从“被动回答”的语言交互,转向“主动行动”的任务执行。ChatGPT开启了大语言模型(LLM)的普及时代,让AI具备了理解和生成人类语言的能力,但它始终停留在“军师”的角色,只能提供方案建议;而OpenClaw的出现,彻底打破了这一局限,将AI变成了能动手干活的“数字员工”,完成了AI从“认知”到“执行”的关键跃迁,成为连接AI能力与现实场景的核心桥梁。 下面我将从技术本质出发,拆解OpenClaw的核心架构、关键技术实现,结合代码示例、架构图与流程图,深入解析其如何实现“行动型AI”的突破,以及为何能被黄仁勋寄予厚望,成为AI产业的下一个里程碑。 一、认知跃迁:从“回答型AI”到“行动型AI”的本质区别 要理解OpenClaw的价值,首先需要明确它与ChatGPT这类“回答型AI”的核心差异。

By Ne0inhk