讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java里volatile关键字如何使用_Javavolatile可见性原理说明

雨浩姑娘_3903

雨浩姑娘_3903

发布时间:2026-01-18 16:48:55

|

679人浏览过

|

来源于php中文网

原创

volatile仅解决变量可见性,不保证原子性;适用于单写多读且写不依赖当前值的场景,如状态标志位;禁止指令重排序,但不保证long/double在32位JVM上的原子写;不延伸至引用对象内部。

在java里volatile关键字如何使用_javavolatile可见性原理说明

volatile 不是用来替代 synchronized 或锁的,它只解决变量的可见性问题,不保证原子性。如果你需要“读-改-写”这类复合操作线程安全(比如 i++),volatile 无效。

volatile 变量必须满足“单次读或单次写”场景

它适用于一个线程写、多个线程读,且写操作不依赖当前值的场景。典型例子是状态标志位:

public class TaskRunner {
    private volatile boolean running = true;

    public void stop() {
        running = false; // 单次写,无依赖
    }

    public void run() {
        while (running) { // 多线程读,每次读都看到最新值
            // do work
        }
    }
}

常见错误是误用于计数器:

❌ volatile int count = 0; 然后在多线程里执行 count++ —— 这会丢失更新,因为 count++ 包含读、加1、写三步,volatile 不保证这三步整体原子。

立即学习“Java免费学习笔记(深入)”;

✅ 正确做法:用 AtomicInteger 或加锁。

volatile 如何禁止指令重排序

JVM 和 CPU 可能对指令重排以优化性能,但 volatile 写操作会插入“StoreStore”屏障,读操作插入“LoadLoad”和“LoadStore”屏障,确保:

YZTurboWebAndroid
YZTurboWebAndroid

YZTurboWebAndroid 高性能 Android WebView 容器 SDK 接入。用于在 Android 项目中集成 WebView 容器,实现: (1) WebView 预加载与复用,提升 H5 页面加载速度 (2) 离线包管理,拦截请求优先命中本地资源 (3) JS Bridge 双向通信,Na...

下载
  • 写 volatile 变量前的所有普通写,不会被重排到该写之后
  • 读 volatile 变量后的所有普通读/写,不会被重排到该读之前

这个特性常用于双重检查锁定(DCL)单例模式中防止对象未初始化完成就被其他线程看到:

public class Singleton {
    private static volatile Singleton instance;

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton(); // 非原子:分配内存 → 初始化 → 赋值给 instance
                }
            }
        }
        return instance;
    }
}

没有 volatile,JVM 可能把“赋值给 instance”提前到“初始化”之前(只要语义合法),导致其他线程拿到一个未构造完的对象。

volatile 不能保证 long/double 的原子写(仅限 32 位 JVM)

Java 规范允许对 64 位变量(long、double)的读写拆成两个 32 位操作,即所谓“非原子性更新”。虽然现代 64 位 JVM 默认已保证原子性,但若目标环境明确是 32 位 JVM(如某些嵌入式或旧 Android 版本),且变量未声明为 volatile,就可能出现“半个 long 值”的问题。

所以:如果变量是 long 或 double,又需跨线程安全读写,必须加 volatile(或用 AtomicLong 等)。

注意:volatile 在这里的作用不是“让写变原子”,而是强制使用原子的读写指令,并禁用重排序——JVM 对 volatile long 的读写总是当作单个不可分割的操作来实现。

真正容易被忽略的是:volatile 的内存语义只作用于它修饰的变量本身,不延伸到该变量引用的对象内部。比如 volatile List<string> list = new ArrayList();</string>,只保证 list 引用的可见性,不保证 list.add() 的线程安全。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2468

2023.11.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5299

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2685

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

3308

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2365

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

3308

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

604

2025.10.23

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

674

2025.10.23

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn