Java的volatile关键字为何不能保证操作的原子性?

2026-04-19 19:050阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1779个文字,预计阅读时间需要8分钟。

Java的volatile关键字为何不能保证操作的原子性?

问题+在讨论原子性操作时,我们经常会听到一个说法:任意一个volatile变量的读写具有原子性,但volatile++这种操作除外。那么问题就是:为什么volatile++不是原子性的?

答案+因为它不是原子操作。volatile关键字确保了变量的可见性和有序性,但它并不能保证复合操作(如++)的原子性。volatile++涉及到多个步骤:首先读取变量的值,然后进行自增,最后写入新的值。即使每个步骤都是原子的,但整个操作序列并不是原子的,因为它们之间可能被其他线程的读写操作打断。

问题

在讨论原子性操作时,我们经常会听到一个说法:任意单个volatile变量的读写具有原子性,但是volatile++这种操作除外。

所以问题就是:为什么volatile++不是原子性的?

答案

因为它实际上是三个操作组成的一个符合操作。

  1. 首先获取volatile变量的值
  2. 将该变量的值加1
  3. 将该volatile变量的值写会到对应的主存地址

一个很简单的例子:

如果两个线程在volatile读阶段都拿到的是a=1,那么后续在线程对应的CPU核心上进行自增当然都得到的是a=2,最后两个写操作不管怎么保证原子性,结果最终都是a=2。每个操作本身都没啥问题,但是合在一起,从整体上看就是一个线程不安全的操作:发生了两次自增操作,然而最终结果却不是3。

阅读全文
标签:

本文共计1779个文字,预计阅读时间需要8分钟。

Java的volatile关键字为何不能保证操作的原子性?

问题+在讨论原子性操作时,我们经常会听到一个说法:任意一个volatile变量的读写具有原子性,但volatile++这种操作除外。那么问题就是:为什么volatile++不是原子性的?

答案+因为它不是原子操作。volatile关键字确保了变量的可见性和有序性,但它并不能保证复合操作(如++)的原子性。volatile++涉及到多个步骤:首先读取变量的值,然后进行自增,最后写入新的值。即使每个步骤都是原子的,但整个操作序列并不是原子的,因为它们之间可能被其他线程的读写操作打断。

问题

在讨论原子性操作时,我们经常会听到一个说法:任意单个volatile变量的读写具有原子性,但是volatile++这种操作除外。

所以问题就是:为什么volatile++不是原子性的?

答案

因为它实际上是三个操作组成的一个符合操作。

  1. 首先获取volatile变量的值
  2. 将该变量的值加1
  3. 将该volatile变量的值写会到对应的主存地址

一个很简单的例子:

如果两个线程在volatile读阶段都拿到的是a=1,那么后续在线程对应的CPU核心上进行自增当然都得到的是a=2,最后两个写操作不管怎么保证原子性,结果最终都是a=2。每个操作本身都没啥问题,但是合在一起,从整体上看就是一个线程不安全的操作:发生了两次自增操作,然而最终结果却不是3。

阅读全文
标签: