【发布时间】:2012-03-07 10:48:57
【问题描述】:
我读过 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");
}
}
运行这个程序的结果是:
第一个线程:countDown 2. d 的值为 1
第二个线程:countDown 2。d的值为1
第一个线程:countDown 1。d的值为2
第二个线程:countDown 1。d的值为2
我知道如果我在程序中添加关键字“静态”, (即“private static volatile int d = 0;”),“d”将增加到 4。 我知道这是因为 d 将成为整个类共享的变量,而不是每个实例都获得一个副本。
结果如下:
第一个线程:countDown 2. d 的值为 1
第一个线程:countDown 1。d的值为3
第二个线程:countDown 2。d的值为2
第二个线程:countDown 1。d的值为4
我的问题是,如果 volatile 应该允许在两个线程之间共享“d”,为什么“private volatile int d = 0;”不会产生类似的结果?也就是说,如果第一个线程将 d 的值更新为 1,那么为什么第二个线程不将 d 的值抓取为 1 而不是 0?
【问题讨论】:
-
感谢那个人(我认为帖子被删除了)表明这是原子性问题。
-
这是我删除您所说的第一个答案。我删除了它,因为在重新阅读您的问题后,我认为这里的问题比简单的“您需要同步”要复杂一些。所以我在下面写了新的答案,专注于我认为真正的问题(理解实例与静态字段、线程和易失性),并简单地提到同步。 :)
标签: java multithreading volatile