使用线程的一个小程序真的让我烦恼,任何人都可以解释为什么这不会给出我认为应该的输出?
class FirstClass {
public static void main(String args[]) {
Class2 two = new Class2();
Thread thread1 = new Thread(two);
thread1.start();
Class3 three =new Class3(two);
Thread thread2 = new Thread(three);
thread2.start();
}
}
class Class2 implements Runnable {
public Boolean variable1 = false;
@Override
public void run() {
System.out.println("Sleeping thread");
try {
Thread.sleep(3000);
}catch(Exception e){}
variable1=true;
System.out.println("Variable 1 = " + variable1);
}
}
class Class3 implements Runnable {
Class2 two;
public Class3(Class2 _two) {
this.two = _two;
}
@Override
public void run() {
while(!this.two.variable1) {
//System.out.println("in while");
}
System.out.println("Variable1 was changed to true");
}
}
上面的,会给我正确的输出,即'sleep thread','variable1 = true','variable1被改为true'。现在,如果我稍微更改程序并取消注释'System.out.println(“in while”);'我没有得到“Variable1被改为true”,它就像它没有突破while循环,但为什么'System.out.println(“in while”)'让它爆发?或者它可能是不是吗?如果有人能解释发生的事情,我将非常感激。
由于
答案 0 :(得分:3)
您正在从多个线程访问two.variable1
而没有任何同步。因此,您有一个可见性问题:第二个线程从其内部缓存中读取变量的值,并且不知道它已被第一个线程更改。
您应该创建变量volatile
,或使用AtomicBoolean
,或使用synchronized方法访问它,以确保将对变量的写入刷新到主内存并读取变量来自主记忆。
对System.out.println()
的调用具有使变量可见的副作用,因为println方法已同步。