【发布时间】:2016-08-30 12:34:01
【问题描述】:
我有两个线程对一个公共变量“n”进行计算,一个线程每次增加“n”,另一个线程每次减少“n”,当我不在这个变量上使用 volatile 关键字时,会发生我无法理解的事情, sb 那里请帮忙解释一下,sn-p 如下:
public class TwoThreads {
private static int n = 0;
private static int called = 0;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
n = 0;
called = 0;
TwoThreads two = new TwoThreads();
Inc inc = two.new Inc();
Dec dec = two.new Dec();
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
while (called != 2) {
//System.out.println("----");
}
System.out.println(n);
}
}
private synchronized void inc() {
n++;
called++;
}
private synchronized void dec() {
n--;
called++;
}
class Inc implements Runnable {
@Override
public void run() {
inc();
}
}
class Dec implements Runnable {
@Override
public void run() {
dec();
}
}
}
1) 我期待的是执行后的“n=0,called=2”,但主线程很可能会在 while 循环中被阻塞;
2) 但是当我取消注释这一行时,程序按预期运行时:
//System.out.println("----");
3) 我知道我应该在“被调用”上使用“volatile”,但我无法解释为什么会发生上述情况;
4)“调用”是在特定线程的工作内存中“读取和加载”,但是为什么在“长”while循环之后它不是“存储和写入”回主线程,如果不是,为什么简单的“打印” " 行可以产生如此大的影响
【问题讨论】:
-
我认为你可以使用 Thread.sleep() 方法而不是 print() 来获得相同的效果。
-
@victor 你是对的,任何一行都可以有同样的效果,无法解释为什么
-
好吧,你无法控制何时执行任何线程;但是主线程将继续执行,当它完成时,另一个线程也将继续执行。这就是为什么你应该使用 Thread.join() 来停止主线程,直到线程的其余部分可以完成。 (Thread.sleep() 会做一段时间,但 join() 会等到他们完成)
标签: java multithreading variables shared volatile