0

wait()これは、との動作をテストするために私が書いたコードですnotify()。今、私はたくさんの疑問を持っています。

class A extends Thread {
  public void run() {
    try {
      wait();
      for (int i = 1; i <= 5; i++) {
        System.out.println(i);
        sleep(500);
      }
    } catch (Exception e) {
    }
    System.out.println("End Of Thread");
  }
}

class ThreadWaitNotify {
  public static void main(String args[]) {
    try {
      A t = new A();
      t.start();
      t.wait();
      t.notify();
      t.join();
      System.out.println("End Of Main");
    } catch (Exception e) {
    }
  }
}

私の質問は次のとおりです。

  1. mainに書き込むt.wait() と、mainはそれ以上実行されず、それ以上再開できません。どうやってするか?
  2. 第二に、私はスレッドでも書いwait()ています。そのため、ループではなく、「End OfThread」のみが出力されますか?私notify()がメインからであろうとなかろうと...
  3. ここでmainに書き込むnotify()と、実行が完了しません。その行にコメントしている間、実行が終了し、「EndOfMain」が出力されます。
4

1 に答える 1

2

私の質問は次のとおりです。

メインに t.wait() を書くと、メインはそれ以上実行されず、それ以上再開できません。どうやってするか?

tmain を実行しているスレッドは、 を呼び出すときにロックを保持しませんt.wait()wait()のJavaDocからわかるように:

例外: IllegalMonitorStateException - 現在のスレッドがオブジェクトのモニターの所有者でない場合。

そのため、wait() を呼び出すと、IllegalMonitorStateException がスローされます。空の catch ブロックは単にエラーを破棄するため、デバッグが困難になります。ex.printStackTrace();を使用してエラーを表示できます。または、チェックされていない例外として再スローできます。

    throw new RuntimeException(ex);

wait() 呼び出しを修正するには、t で同期する必要があります。

synchronized (t) {
    t.wait();
}

notify() を呼び出すときも、同じロックを保持する必要があります。

次に、ループではなく「スレッドの終わり」のみを出力するため、スレッドにもwait()を記述しましたか?メインからnotify()しても...

ここでも同じことが起こっていますが、別のスレッドで発生しています。作成した新しいスレッドは t のロックを所有していないため、wait()呼び出しは例外をスローします。繰り返しますが、例外を正しく処理しないことで、例外を破棄しています。

今、メインに notify() を書くと、実行が完了しません。その行にコメントしている間、実行が終了し、「メインの終了」が出力されます。

「wait() と notify() の呼び出しをコメントアウトする」という意味だと思います。これは予期されることです。run() メソッドが終了しました。つまり、スローされてメソッドの最後まで実行された IllegalMonitorStateException をキャッチしました。スレッドの実行が完了すると、join() メソッドが戻ります。これは、wait() 呼び出しがすぐに例外をスローするため、ほとんどすぐに発生します。

于 2012-11-15T14:08:23.037 に答える