java - 为什么 Java 中的 volatile 不更新变量的值?

标签 java multithreading volatile

我读到 Java 中的“volatile”允许不同的线程访问同一字段并查看其他线程对该字段所做的更改。如果是这种情况,我会预测当第一个和第二个线程完全运行时,“d”的值将增加到 4。但相反,每个线程将“d”的值增加到 2。

public class VolatileExample extends Thread {
private int countDown = 2;
private volatile int d = 0; 

    public VolatileExample(String name) {
        super(name);
        start();
    }

    public String toString() {
       return super.getName() + ": countDown " + countDown;
    }

public void run() {
        while(true) {
        d = d + 1;
    System.out.println(this + ". Value of d is " + d);
    if(--countDown == 0) return;
    }
}

public static void main(String[] args) {
    new VolatileExample("first thread");
    new VolatileExample("second thread");
    }
}

运行这个程序的结果是:

first thread: countDown 2. Value of d is 1

second thread: countDown 2. Value of d is 1

first thread: countDown 1. Value of d is 2

second thread: countDown 1. Value of d is 2

我知道如果我在程序中添加关键字“static”, (即“private static volatile int d = 0;”),“d”将增加到 4。 我知道那是因为 d 将成为整个类共享的变量,而不是每个实例都获得一个副本。

结果如下:

first thread: countDown 2. Value of d is 1

first thread: countDown 1. Value of d is 3

second thread: countDown 2. Value of d is 2

second thread: countDown 1. Value of d is 4

我的问题是,如果 volatile 应该允许在两个线程之间共享“d”,为什么“private volatile int d = 0;”不会产生类似的结果?也就是说,如果第一个线程将 d 的值更新为 1,那么为什么第二个线程不将 d 的值获取为 1 而不是零?

最佳答案

volatile 不允许“共享”任何东西。它只是防止变量被缓存在线程本地,以便立即发生对变量值的更改。您的 d 变量是一个实例变量,因此由持有它的实例拥有。您需要重新阅读线程教程以重新调整您的假设。

一个不错的引用是 here

关于java - 为什么 Java 中的 volatile 不更新变量的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9304496/

相关文章:

c - 将数组传递给 C 中的线程例程

c# - 线程 :Lock on generic dictionary

java同步问题

java - final 变量和 lazySet 实现都需要 LoadStore 和 StoreStore 吗?

java - 集群java独立应用程序

java - JPanel 子类中的重写 Paint() 函数从未被调用?

java - 如果用户未输入任何内容,我如何验证整数字段?

java - 在Java中减去两个日期

Python:使用多线程通过 gzip 传输 MySQL 数据库的 mysqldump 输出挂起

c++ - "pseudo-atomic"C++ 操作