2016-04-04 46 views
0

我遇到了一個令人難以置信的奇怪現象。我目前正在使用Java編寫即時通訊程序,並且我有一個變量來表示新用戶是否已連接(這是在單獨的類中)。這是有問題的地方對象ListenerThread extends Thread代碼:System.out.println影響執行邏輯的線路

boolean listenerThreadConnected = ServerDriver.getListenerThread().connected; 
System.out.println("Whatever in here"); 
if(listenerThreadConnected){ 
    ... 
    System.out.println("In the if statement"); 
    ... 
} 

因此,此代碼的工作。當listenerThreadConnected = true執行if語句時,它輸出In the if statement並執行if語句中的所有其他內容。然而,除了註釋掉System.out.println("Whatever in here")if聲明沒有觸發,並且沒有輸出In the if statement的符號之外,我沒有更改其他代碼。我的代碼看起來像這樣:

boolean listenerThreadConnected = ServerDriver.getListenerThread().connected; 
//System.out.println("Whatever in here"); 
if(listenerThreadConnected){ 
    ... 
    System.out.println("In the if statement"); 
    ... 
} 

我很困惑。這個System.out.println怎麼會影響實際的邏輯?我知道這個問題非常開放,但你有沒有過類似的經歷?對於某些上下文,這全部在while循環中,並且ListenerThread是併發運行的線程。我似乎無法複製這個結果,除了在我目前的代碼。

[編輯]更換System.out.printlnThread.sleep(1)也似乎工作,所以這使我覺得這是一種併發問題。

回答

4

並非如此交流中心所有,你肯定在多線程系統和您的應用程序越來越過時的boolean值,你是在讀變量listenerThreadConnected

如何時需要確保存儲可見性:?

聲明此boolean listenerThreadConnected爲易失性,錯誤必須消失!

+0

非常感謝。對於多線程和併發來說很新穎。 – dsiegler19

2

請注意,System.out.println通常實現爲​​(即使沒有記錄),以便您不會得到兩個線程交錯的輸出。

執行該語句的效果是對執行同步方法的線程可見的變量進行更新(這是「發生之前」關係)。

通過刪除System.out.println調用,您刪除此行爲,因此您可能會看到過時的變量。

作爲@ Xoce웃Pepeúpa說,使變量volatile或做其他事情以確保內存可見性(例如將其更改爲AtomicBoolean)。