0

私は信じられないほど奇妙な現象に遭遇しました。私は現在、Javaでインスタント・メッセンジャー・プログラムをプログラミングしており、新しいユーザーが接続しているかどうかを表す変数を持っています(別のクラスにあります)。System.out.println行がロジックの実行に影響する

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

ので、このコードは動作します:ここではオブジェクトListenerThread extends Threadは、問題のコードです。 listenerThreadConnected = trueifステートメントが実行され、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は同時に実行されるスレッドです。私は現在のコードを除いてこの結果を複製することはできません。 Thread.sleep(1)System.out.printlnの交換

[EDIT]も動作しているようですので、これはそれが同時実行の問題であることを考えるように私をリード。

答えて

4

ないので全然extrange、あなたはマルチスレッドシステムで確認するためのもので、変数

どうをlistenerThreadConnected読むときにアプリが古いboolean値を取得し、あなたはメモリの視認性を確保する必要がありますされ:?

このboolean listenerThreadConnectedを揮発性と宣言し、エラーをなくしてください!

+0

ありがとうございます。マルチスレッド化と同時実行性にはまったく新しいものです。 – dsiegler19

2

System.out.printlnは、2つのスレッドのインターリーブ出力が得られないように、しばしば​​として実装されています(これは文書化されていません)。

このステートメントを実行すると、synchronizedメソッドが実行されているスレッドで変数を更新できるようになります(これは「起こる」関係です)。

System.out.printlnコールを削除すると、この動作が削除されるため、古い変数が表示されることがあります。

@Xoce웃는ぺプパによると、変数volatileを作成するか、メモリの可視性を確保するために何か他の処理を行います(AtomicBooleanに変更するなど)。

関連する問題