我读到 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/