volatile 修饰 i++ 安全吗
不安全。volatile 只能保证变量可见性和禁止指令重排序,无法保证复合操作(如自增)的原子性。在多线程环境下,多个线程同时执行 i++ 会导致数据竞争,最终结果小于预期值。

为什么 i++ 不是原子操作
因为 i++ 在字节码层面被分解为读取、修改和写入三个步骤,中间可能被其他线程打断。

public class VolatileCounter {
private volatile int i = 0;
public void increment() {
i++; // 非原子操作
}
public int getI() {
return i;
}
public static void main(String[] args) throws InterruptedException {
VolatileCounter counter = new VolatileCounter();
Thread t1 = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final i: " + counter.getI()); // 通常小于 20000
}
}如何修复此问题
使用 AtomicInteger 或 synchronized 来保证原子性。
立即学习“Java免费学习笔记(深入)”;

import java.util.concurrent.atomic.AtomicInteger;
public class SafeCounter {
private AtomicInteger i = new AtomicInteger(0);
public void increment() {
i.incrementAndGet(); // 原子操作
}
public int getI() {
return i.get();
}
public static void main(String[] args) throws InterruptedException {
SafeCounter counter = new SafeCounter();
Thread t1 = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int j = 0; j < 10000; j++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final i: " + counter.getI()); // 始终等于 20000
}
}


















