1
class Test {

    public static void main(String[] args) {

        System.out.println("1.. ");
        synchronized (args) {

            System.out.println("2..");

            try {
                Thread.currentThread().wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("3..");
        }

    }
}

IllegalMonitorStateExceptionこのコードでモニター例外が発生しています。私の理解によると、文字列配列オブジェクトである同期ブロックのためargs、現在のスレッドはロックを取得している必要があり、wait メソッドを使用してロックを解放しています。

誰かがこの例外の背後にある理由を説明できますか?

4

3 に答える 3

4

に電話wait()していThread.currentThread()ます。オブジェクトを呼び出す前に、このオブジェクトで同期する同期ブロックを使用して、このオブジェクトwait()のモニターを所有する必要があります。だから欠けているのは

synchronized(Thread.currentThread()) {
    Thread.currentThread().wait();
}

とは言っても、 Thread オブジェクトの呼び出しはすべきことではありません。特に、またはを呼び出す他のスレッドがないことを考えると、wait()何をするのか理解していないことをおそらく示しています。main メソッドに渡された引数を同期することも、非常に奇妙な選択です。は非常に低レベルのメソッドであり、その機能を完全に理解している場合でも、めったに使用しないでください。より良い答えを得るには、このコードで実際に何をしたいのかを説明する必要があります。wait()notify()notifyAll()wait()

于 2013-07-07T14:59:37.530 に答える
3

ドキュメントからIllegalMonitorStateException

スレッドがオブジェクトのモニターで待機しようとしたことを示すため、または指定されたモニターを所有せずにオブジェクトのモニターで待機している他のスレッドに通知するためにスローされます。

ドキュメントからObject#notify()

スレッドは、次の 3 つの方法のいずれかで、オブジェクトのモニターの所有者になります。

  • そのオブジェクトの同期インスタンス メソッドを実行する。
  • オブジェクトで同期する同期ステートメントの本体を実行する
  • Class 型のオブジェクトの場合、そのクラスの同期された静的メソッドを実行します。

したがって、スレッドはargsオブジェクトで同期されたブロックを実行しているため

synchronized (args) {
    //...
}

args.wait()代わりにを呼び出す必要がありますThread.currentThread().wait();

于 2013-07-07T15:01:22.653 に答える