为什么在多线程写入值的情况下不能使用 volatile

why volatile can't be used in the case where one more threads will write value

很多文档提示我们不能用volatile当多一个线程要写值的时候,比如有一个boolean对象isRun,如果两个线程或者多个线程调用setIsRun(true/false),我们不能用volatile修饰变量count.

据我所知,volatile可以使所有线程都可见最新值,那为什么我们不能在上述情况下使用它呢?任何人都可以告诉我这件事,谢谢!

如你所说。

volatile - 保证线程之间的可见性。

synchronized - 保证线程间的原子性和可见性。

示例:

假设有两个线程 A 和 B 都可以访问以下变量。

public volatile int count = 0;

如果线程 A 执行以下操作

count++;

不保证 JVM 执行 ++ 操作,这是实际的 3 个 JVM 操作(读取、递增、写入)原子操作。如果存在竞争条件,线程 B 有可能看到过时的值被分配给 count

如果你想要原子性你需要使用synchronized

示例:

假设有两个线程 A 和 B 都可以访问以下变量和 increment 方法。

private volatile int count = 0;

public synchronized void increment() {
    count++;
}

现在,如果线程 A 进入 increment 方法,它将获得一个实例级监视器锁,只有当它存在 increment 方法时才会释放该锁。这保证了JVM指令读、递增、写一个接一个执行。