Java 面试题
目录

Java 中 volatile 能保证原子性吗?

· 约 3 分钟读完 · 第 64 / 274 章

推荐答案

volatile 关键字不能保证原子性。它只能保证变量的可见性和有序性,但不能保证复合操作的原子性。

本题详细解读

1. volatile 的作用

volatile 关键字在 Java 中有两个主要作用:

  • 可见性:当一个线程修改了 volatile 变量的值,其他线程可以立即看到这个修改。
  • 有序性:volatile 会禁止指令重排序,确保代码的执行顺序与程序的顺序一致。

2. 原子性

原子性是指一个操作是不可分割的,要么全部执行成功,要么全部不执行。常见的原子操作包括:

  • 基本类型的读取和赋值(如 int、boolean 等)。
  • 引用类型的赋值。

然而,复合操作(如 i++)并不是原子操作,因为它包含了读取、修改和写入三个步骤。

3. volatile 不能保证原子性的原因

volatile 只能保证单个读/写操作的原子性,但不能保证复合操作的原子性。例如,i++ 操作虽然包含了对 volatile 变量的读和写,但由于这两个操作是分开的,因此 volatile 无法保证整个操作的原子性。

4. 示例代码

在这个例子中,increment() 方法中的 count++ 操作并不是原子的,即使 count 是 volatile 的。

5. 如何保证原子性

如果需要保证原子性,可以使用以下方法:

  • 使用 synchronized 关键字。
  • 使用 java.util.concurrent.atomic 包中的原子类,如 AtomicInteger。

在这个例子中,AtomicInteger 的 incrementAndGet() 方法是原子的,因此可以保证操作的原子性。