Discuss / Java / 请问为什么不能用 volatile 代替 synchronized?

请问为什么不能用 volatile 代替 synchronized?

Topic source

廖神,前面说到 volatile 有两个作用:

  • 每次访问变量后,总是获取主内存的最新值

  • 每次修改变量后,立即回写到主内存

是不是意味着 volatile 可以达到同步变量的作用?

请问这一段代码里,为什么用 volatile 会导致结果不对呢?

public class Main {
    public static void main(String[] args) throws Exception {
        var add = new AddThread();
        var dec = new DecThread();
        add.start();
        dec.start();
        add.join();
        dec.join();
        System.out.println(Counter.count);
    }
}

class Counter {
    public volatile static int count = 0;
}

class AddThread extends Thread {
    public void run() {
        for (int i = 0; i < 10000; i++) {
            Counter.count += 1;
        }
    }
}

class DecThread extends Thread {
    public void run() {
        for (int i = 0; i < 10000; i++) {
            Counter.count -= 1;
        }
    }
}

廖雪峰

#2 Created at ... [Delete] [Delete and Lock User]

volatile只保证:

  1. 读主内存到本地副本;
  2. 操作本地副本;
  3. 回写主内存。

这3步多个线程可以同时进行。

半死态

#3 Created at ... [Delete] [Delete and Lock User]

是不是volatile不能保证变量的原子性的缘故?

廖雪峰

#4 Created at ... [Delete] [Delete and Lock User]

是保证时效性不是原子性

谢谢廖神回复!有点理解了,也就是说 volatile 只保证变量改动之后立刻回写,之后的新线程读取到的肯定是更新后的值,但之前已经获取过此变量本地副本的线程无法得知主内存中这个变量有了修改。


  • 1

Reply