【问题标题】:why volatile can't be used in the case where one more threads will write value为什么 volatile 不能在多线程写入值的情况下使用
【发布时间】:2016-01-13 04:37:58
【问题描述】:

很多文档提示我们不能使用volatile,当多线程写入值时,例如,有一个布尔对象isRun,如果两个或更多线程调用setIsRun(true/false),我们不能使用volatile 修饰变量count

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

【问题讨论】:

    标签: java multithreading volatile


    【解决方案1】:

    如你所说。

    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 指令读取、递增、写入一个接一个地执行。

    【讨论】:

    • 问题是关于一个布尔值。
    • 抱歉,我已将问题更新为与 boolean 变量有关,因此它与原子性无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-06
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多