2013-03-09 46 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