3

以下のコードは、(これを使用して) 現在のスレッドに通知した後でも実行されません。

public synchronized void test() {
    String str = new String();
    try {
        System.out.println("Test1");
        this.wait();
        this.notifyAll();
        System.out.println("Test2");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("Inside exception");
        e.printStackTrace();
    }
 }

Test1コンソールの出力としてのみ取得します。

2 番目のケースでは、文字列オブジェクトで wait メソッドを呼び出すと例外が発生します。その理由は、文字列クラス オブジェクトstrが現在のオブジェクトのロックを保持していないためです。しかし、私はstr.wait()実際に何を意味するのだろうか?

public synchronized void test() {
    String str = "ABC";
    try {
        System.out.println("Test1");
        str.wait();
        str.notifyAll();
        System.out.println("Test2");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("Ins");
        e.printStackTrace();
    }
 }

コンソール出力:

> Test1  
java.lang.IllegalMonitorStateException
4

5 に答える 5

7

そのコードから何を期待したかわからない:

  1. 最初の例でwaitは、それが言うことを行います:それは待機するため、notifyAll呼び出されることはありません
  2. wait2 番目の例では、最初にそのオブジェクトのモニターを保持しないと、そのオブジェクトを呼び出すことはできません。したがってsynchronized(str)、例外を回避するにはブロックに入る必要があります。しかし、あなたはまだ1と同じ問題を抱えているでしょう.

waitandの主な使用例は、notifyスレッド間通信です。つまり、1 つのスレッドが待機し、別のスレッドが、待機中のスレッドが起動できることを通知します。あなたの場合、同じスレッドが通信チャネルの両端にあり、機能しません。

于 2012-12-21T12:19:00.173 に答える
3

wait同じスレッドでと をnotify次々に呼び出してはいけません。それらは異なるスレッドから実行する必要があります。何かを待つ場合、他のスレッドが通知するまで、制御はそのスレッドで先に進みません

于 2012-12-21T12:18:58.973 に答える
3

適切な使用方法を学ぶ必要がwait()ありnotify()ます。Effective Java (Josh Bloch) から:

// The standard idiom for using the wait method
synchronized (obj) {
    while (<condition does not hold>)
    obj.wait(); // (Releases lock, and reacquires on wakeup)
    ... // Perform action appropriate to condition
}

これにより、現在のスレッドは条件が真になるまで適切に待機します。この条件が真になると、他のスレッドはnotify()orを呼び出す必要があります。notifyAll()

しかし、Josh からのより重要なアドバイスは次のとおりです。

于 2012-12-21T12:30:07.350 に答える
0

最初のケースに関して: wait は、別のスレッドが notify() メソッドまたは notifyAll() メソッドを呼び出すまで、現在のスレッドを待機させます。したがって、別のスレッド内で実行しない限り、notify all が呼び出されることはありません。

于 2012-12-21T12:21:05.733 に答える
0

最初のスニペットでは、 を呼び出したときにインスタンスを待機するためにスレッドがキューに入れられますwaitnotifyAll踏み板が既に待機しているため、 は実行されません。

通知は別のトレッドで実行する必要があります。

于 2012-12-21T12:23:43.317 に答える