news 2026/4/23 11:20:26

Java中volatile的介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java中volatile的介绍


一、volatile的特性

当声明共享变量为volatile后,对这个变量的读/写将会很特别。理解volatile特性的一个好方法是把对volatile变量的单个读/写(不是类似val++的复合操作),看成是使用同一个锁对这些单个读/写操作做了同步。下面通过具体的示例来说明。

class VolatileFeaturesExample { volatile long vl = 0L; // 使用volatile定义一个64位的long型的共享变量v1 public void set(long l) { vl = l; // 单个volatile变量的写 } public void getAndIncrement() { vl++; // 复合(多个)volatile变量的读/写,存在竞态条件,线程不安全,需要加锁 } public long get() { return vl; // 单个volatile变量的读 } }

假设有多个线程分别调用上面程序的3个方法,这个程序在语义上和下面程序等价。

class VolatileFeaturesExample1 { long vl = 0L; // 定义一个64位的long型普通变量 public synchronized void set(long l) {// 对单个的普通变量的写用同一个锁同步,锁对象为this vl = l; } public void getAndIncrement() { // 普通方法调用 long temp = get(); // 调用已同步的读方法 temp += 1L; // 普通写操作,存在竞态条件,线程不安全,需要加锁 set(temp); // 调用已同步的写方法 } public synchronized long get() { // 对单个的普通变量的读用同一个锁同步,锁对象为this return vl; } }

如上面示例程序所示,一个volatile变量的单个读/写操作,与一个普通变量的读/写操作都是使用同一个锁来同步,它们之间的执行效果相同。

注意:上面的getAndIncrement()方法是非线程安全的,因为其中存在竞态条件(value++实际上包含三个独立的操作:1 读取value;2 将 value加1;3 将计算结果写入value)

锁的happens-before规则保证释放锁和获取锁的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。锁的语义决定了临界区代码的执行具有原子性。这意味着,即使是64位的long型和double型变量,只要它是volatile变量,对该变量的读/写就具有原子性(单个volatile变量)。如果是多个volatile操作或类似于volatile++这种复合操作整体上不具有原子性。

volatile变量自身具有下列特性

可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。

原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。

二、volatile写-读建立的happens-before关系

从内存语义的角度来说,volatile的写-读与锁的释放-获取有相同的内存效果:volatile写和锁的释放有相同的内存语义;volatile读与锁的获取有相同的内存语义。请看下面使用volatile变量的示例代码。

class VolatileExample { int a = 0; volatile boolean flag = false; public void writer() { a = 1; // 1 flag = true; // 2 } public void reader() { if (flag) { // 3 int i = a; // 4 System.out.println("i=" + i); } } }

假设线程A执行writer()方法之后,线程B执行reader()方法。根据happens-before规则,这个过程建立的happens-before关系可以分为3类:

1)根据程序次序规则 1 happens-before 2;3 happens-before 4。

2)根据volatile规则 2 happens-before 3。

3)根据happens-before的传递性规则 1 happens-before 4。

三、volatile写-读的内存语义

volatile写的内存语义如下,当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存

以上面示例程序VolatileExample为例,假设线程A首先执行writer()方法,随后线程B执行reader()方法,初始时两个线程的本地内存中的flag和a都是初始状态。图3-17是线程A执行volatile写后,共享变量的状态示意图。

如图所示线程A在写flag变量后,本地内存A中被线程A更新过的两个共享变量的值被刷新到主内存中。此时,本地内存A和主内存中的共享变量的值是一致的。

四、volatile读的内存语义如下

当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

如图所示,在读flag变量后,本地内存B包含的值已经被置为无效。此时,线程B必须从主内存中读取共享变量。线程B的读取操作将导致本地内存B与主内存中的共享变量的值变成一致。

如果我们把volatile写和volatile读两个步骤综合起来看的话,在读线程B读一个volatile变量后,写线程A在写这个volatile变量之前所有可见的共享变量的值都将立即变得对读线程B可见。

下面对volatile写和volatile读的内存语义做个总结。(重点理解下面的总结)

>线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所做修改的)消息。

>线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。

>线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 12:33:46

【限时干货】智普AutoGLM私有化部署仅需6步,第5步最关键

第一章:智普Open-AutoGLM部署概述智普AI推出的Open-AutoGLM是一个面向自动化任务的大型语言模型系统,支持自然语言理解、代码生成与智能推理等多种功能。该系统基于GLM架构进行优化,适用于企业级自动化场景,如智能客服、文档处理和…

作者头像 李华
网站建设 2026/4/18 10:16:45

ADBKeyBoard:Android自动化输入难题的终极解决方案

ADBKeyBoard:Android自动化输入难题的终极解决方案 【免费下载链接】ADBKeyBoard Android Virtual Keyboard Input via ADB (Useful for Test Automation) 项目地址: https://gitcode.com/gh_mirrors/ad/ADBKeyBoard 在Android自动化测试和脚本操作领域&…

作者头像 李华
网站建设 2026/4/18 2:18:47

深度解析:现代化富文本编辑器的架构设计与实战应用

在当今内容驱动的互联网时代,选择一个既强大又灵活的富文本编辑器已成为开发团队的技术必修课。wangEditor-next作为基于Slate.js框架的开源解决方案,为开发者提供了从基础编辑到高级扩展的完整技术栈,彻底改变了传统编辑器的使用体验。 【免…

作者头像 李华
网站建设 2026/4/14 0:30:22

5步掌握开源机械臂控制:从仿真到实物的完整实践指南

5步掌握开源机械臂控制:从仿真到实物的完整实践指南 【免费下载链接】open_manipulator OpenManipulator for controlling in Gazebo and Moveit with ROS 项目地址: https://gitcode.com/gh_mirrors/op/open_manipulator 想要快速上手机械臂控制却不知从何开…

作者头像 李华
网站建设 2026/4/16 13:40:59

AI游戏助手终极指南:完整使用教程与实战技巧

AI游戏助手终极指南:完整使用教程与实战技巧 【免费下载链接】Aimmy Universal Second Eye for Gamers with Impairments (Universal AI Aim Aligner - YOLOv8) 项目地址: https://gitcode.com/gh_mirrors/ai/Aimmy 想要在游戏中获得精准的瞄准能力&#xff…

作者头像 李华
网站建设 2026/4/22 1:35:13

IPATool终极指南:轻松获取App Store应用安装包的完整解决方案

你是否曾经为获取iOS应用安装包而烦恼?传统方法要么需要复杂的开发者账号流程,要么依赖越狱设备,操作繁琐且效率低下。今天,我要向你揭秘一个革命性的命令行工具——IPATool,它将彻底改变你获取App Store应用的方式。 …

作者头像 李华