温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

为什么volatile不保证原子性

发布时间:2026-10-07 20:16:57 来源:亿速云 阅读:91 作者:小樊 栏目:编程语言

volatile 关键字在 Java 中主要解决的是可见性和禁止指令重排序的问题,而不保证原子性。下面从原理层面解释“为什么”。


一、volatile 做了什么?

volatile 有两个核心作用:

  1. 可见性
    当一个线程修改了 volatile 变量,其他线程能立刻看到最新值(通过主内存同步)。

  2. 禁止指令重排
    在 volatile 写/读前后插入内存屏障,保证特定顺序。

⚠️ 但:volatile 不保证多个操作整体一次性完成。


二、为什么不能保证原子性?

原子性是什么?

原子性 = 一个操作不可被中断,要么全部执行,要么完全不执行。

例如:

i++;

这其实是 3 步操作:

  1. 读取 i
  2. 计算 i + 1
  3. 写回 i

volatile 只保证“写回可见”,不保证“过程不被打断”

示例:

volatile int count = 0;

// 线程 A
count++;

// 线程 B
count++;

执行可能过程如下:

线程A: 读 count = 0
线程B: 读 count = 0
线程A: count = 1
线程B: count = 1

最终结果:count = 1(错误)

原因:

  • volatile 保证你读的是最新值
  • 但 读 → 改 → 写 不是一次性完成的
  • 线程切换发生在中间

三、对比:什么能保证原子性?

方式 是否原子 说明
volatile ❌ 只保证可见
synchronized ✅ 锁保证互斥
AtomicInteger ✅ CAS 原子指令
Lock ✅ 类似 synchronized

示例(正确写法):

AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); // 原子操作

四、什么时候 volatile 足够?

✅ 适合场景:

  • 状态标志(true/false)
  • 一次性赋值
  • 双重检查单例(配合 class 初始化)

❌ 不适合:

  • 计数器
  • 复合操作(i++, check-then-act)

五、一句话总结

volatile 保证“看到最新值”,但不保证“操作不被拆开执行”,所以不保证原子性。

如果你愿意,我也可以画一张内存模型示意图或结合CPU 缓存一致性来讲。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手