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 = true」、「変数1がtrueに変更されました」という正しい出力を提供します。ここで、プログラムを少し変更して、'System.out.println("in while");' のコメントを外します。「Variable1 が true に変更されました」というメッセージが表示されません。while ループから抜け出していないようですが、なぜ「System.out.println("in while")」で抜け出すのでしょうか?誰かが何が起こっているのか説明できれば、私は最も感謝しています.

ありがとう

4

1 に答える 1

3

two.variable1同期せずに複数のスレッドからにアクセスしています。したがって、可視性の問題があります。2番目のスレッドは、内部キャッシュから変数の値を読み取り、最初のスレッドによって変更されたことを認識しません。

変数への書き込みがメインメモリにフラッシュされ、変数がメインメモリから読み取られるようにするには、変数を作成するか、をvolatile使用するか、同期メソッドを使用してアクセスする必要があります。AtomicBoolean

toを呼び出すとSystem.out.println()、printlnメソッドが同期されるため、変数が表示されるという副作用があります。

于 2013-03-09T11:19:51.563 に答える