Javaのwait()とnotify()を使用するときにIllegalMonitorStateExceptionを回避するにはどうすればよいですか?

Barbara Streisand
リリース: 2024-11-02 10:13:30
オリジナル
530 人が閲覧しました

How Do You Avoid IllegalMonitorStateException When Using Java's wait() and notify()?

Java の待機と通知: IllegalMonitorStateException について

Java では、wait() メソッドとnotify() メソッドを使用してスレッドを同期します。ただし、不適切に使用すると、IllegalMonitorStateException が発生する可能性があります。

問題

以下のコード スニペットは、単純な同期の問題を示しています。

<code class="java">class Main {
    // ...
    public void wait() {
        // ...
    }
    public void notifyAll() {
        // ...
    }
}

class Runner implements Runnable {
    public void run() {
        try {
            Main.main.wait();
        } catch (InterruptedException e) {
            // ...
        }
    }
}</code>
ログイン後にコピー

この例では、Runner スレッドは Main オブジェクトに対して wait() を呼び出そうとします。ただし、ランナー スレッドはメイン オブジェクトに関連付けられたモニターを所有していないため、例外が発生します。

同期メソッドについて

wait() を使用して通知するには() の場合、現在のスレッドは同期されるオブジェクトのモニターを所有している必要があります。これは、synchronized キーワードを使用してオブジェクトを同期することで実現できます。

解決策

問題を解決するには、Runner クラスを次のように変更できます。

<code class="java">class Runner implements Runnable {
    public void run() {
        try {
            synchronized(Main.main) {
                Main.main.wait();
            }
        } catch (InterruptedException e) {
            // ...
        }
    }
}</code>
ログイン後にコピー

wait() 呼び出しの周囲に同期ブロックを追加することで、Runner スレッドは Main オブジェクトのモニターの所有者になり、待機操作を安全に実行できます。

notifyAll に適用

同じ原則がnotify() メソッドとnotifyAll() メソッドに適用されます。これらは、同期されるオブジェクトの同期ブロック内から呼び出される必要があります。したがって、Main クラスは次のように変更できます。

<code class="java">class Main {
    // ...
    public synchronized void notifyAll() {
        // ...
    }
}</code>
ログイン後にコピー

モニターの適切な所有権を確保することで、wait() と Notice() の使用を安全に実装して Java のスレッドを同期できます。

以上がJavaのwait()とnotify()を使用するときにIllegalMonitorStateExceptionを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート