2013-03-09 61 views
0

使用线程的小程序真的让我感到困扰,任何人都可以解释为什么这不会给出我认为应该是的输出?线程没有给出正确的输出

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"); 
    } 
} 

以上,会给我正确的输出,即'睡眠线程','变量1 =真','变量1变为真'。现在,如果我稍微改变程序并取消注释'System.out.println(“in while”);'我没有得到“变量1被更改为真”,就好像它没有跳出while循环,但为什么'System.out.println(“in while”)'使它突然出现?或者,也许它是不是如果有人可以解释发生了什么事我将不胜感激

感谢

+0

尝试使变量易变 – radai 2013-03-09 11:18:43

+0

可能重复的[Loop没有看到更改的值没有打印语句](http://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without- a-print-statement) – Boann 2014-08-23 10:24:54

回答

3

您正在访问从多个线程two.variable1没有任何形式的同步让您拥有一个知名度问题:?。第二线程从其内部缓存中读取变量的值,并且不知道它已被第一个线程更改。

您应该使变量volatile或使用AtomicBoolean,或使用同步方法对其进行访问,以确保将写入变量的内容刷新到主内存,并从主内存中读取变量。

System.out.println()的调用具有使变量可见的副作用,因为println方法是同步的。

+0

非常感谢您的解释。 – 2013-03-09 11:25:30