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

Object.wait() を常に同期ブロック内で呼び出す必要があるのはなぜですか?

DDD
DDDオリジナル
2024-12-14 09:25:12440ブラウズ

Why Must Object.wait() Always Be Called Within a Synchronized Block?

予測可能性を確保するために必要な Wait() の同期

スレッドの安全性を保証し、IllegalMonitorStateException を防ぐために、Object.wait() は同期されたブロック内に存在する必要があります。

同期の理由Requirement

Wait は、オブジェクトに関連付けられたモニターを解放し、他のスレッドがそれを取得できるようにします。 wait() が同期ブロックの外で呼び出される可能性がある場合、予期しない動作が発生する可能性があります。

同期なしの Wait() の潜在的な危険

同期 wait() なしのブロッキング キューの実装を検討してください:

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

    public void give(String data) {
        buffer.add(data);
        notify(); // Signal waiting consumer
    }

    public String take() throws InterruptedException {
        while (buffer.isEmpty()) {
            wait(); // Suspend thread without synchronization
        }
        return buffer.remove();
    }
}

この中で例:

  1. コンシューマ スレッドは take() を呼び出し、バッファが空であることを確認し、その後同期せずに wait() を呼び出すことがあります。
  2. コンシューマ スレッドが実際にスリープする前に、プロデューサ スレッドはバッファに要素を追加し、待機中のスレッドに通知する可能性があります。
  3. ただし、コンシューマ スレッドは、要素が不足しているために通知を見逃している可能性があります。
  4. プロデューサ スレッドはその後コンシューマに通知しない可能性があり、その結果デッドロックが発生します。

ユニバーサル同期の問題

この同期の問題は待機/通知に全般的に適用されます。特定の実装に関係なく、メカニズム。同期がないと、競合状態や予測できないスレッドの動作が発生するリスクが常にあります。したがって、「同期内で待機」ルールによりスレッドの安全性が確保され、そのような問題が防止されます。

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

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