ホームページ >Java >&#&チュートリアル >Java の同期ブロック内で「wait()」を呼び出す必要があるのはなぜですか?

Java の同期ブロック内で「wait()」を呼び出す必要があるのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-09 07:05:11773ブラウズ

Why Must `wait()` Be Called Inside a Synchronized Block in Java?

wait() が同期ブロック内に存在する必要がある理由

同期ブロック内での Object.wait() の呼び出しの強制は、重要な役割を果たします。 Java の同時実行モデルの目的。この制限に従わない場合は IllegalMonitorStateException が発生しますが、この制限の背後にある理論的根拠を理解することが重要です。

同期 Wait() の理由

wait() は、同期されたオブジェクトに関連付けられたモニター。 wait() を呼び出す前にモニターを明示的に取得すると、待機操作が発生したときに呼び出しスレッドがモニターを排他的に保持することが保証されます。これにより、呼び出し側スレッドが待機している間、他のスレッドが共有状態を変更できないことが保証されます。

同期ブロック外での Wait() の結果

If wait() が可能である場合同期ブロックの外で呼び出される場合、さまざまな問題が発生する可能性があります。次のシナリオを考えてみましょう:

例: ブロッキング キュー

コンシューマー スレッドがキューから要素を取得し、プロデューサー スレッドが要素を追加できるブロッキング キューを想像してください。行列に。同期なし:

class BlockingQueue {
    Queue<String> buffer = new LinkedList<>();

    void take() throws InterruptedException {
        while (buffer.isEmpty()) {
            // Suspend thread without acquiring the monitor
            wait();
        }
    }
}

潜在的な問題:

  • 競合状態: プロデューサ スレッドはバッファに要素を追加できますが、コンシューマ スレッドは、次の理由により、notify() 呼び出しを見逃す可能性があります。すでに wait() に入っています。
  • デッドロック: コンシューマ スレッドが中断されたままである一方で、プロデューサ スレッドは空のバッファを待ってブロックされる可能性があります。気づかれない Notify() が原因です。

ユニバーサル同期要件

この同期の問題は、ブロック キューの例に限定されません。 wait() と Notice() を使用したスレッド通信を伴うシナリオでは、競合状態や潜在的なデッドロックを防ぐために同期が必要です。

Waiter と Notifier 間の合意

Synchronized wait()ウェイター スレッド (消費) と通知スレッド (生成) が共有リソース (述語) の状態に同意することを保証します。この合意により、ウェイターが待つ前に述語を正しくチェックし、脆弱な期間中に通知を見逃さないことが保証されます。

上記の例では、述語はbuffer.isEmpty()です。同期により、バッファが本当に空の場合にのみコンシューマ スレッドが自身を一時停止することが保証されます。

以上がJava の同期ブロック内で「wait()」を呼び出す必要があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。