1. ホーム

[解決済み】Javaのspurious wakeupは実際に起こるのでしょうか?

2022-04-10 21:52:10

質問

ロックに関する様々な質問を見ていると、(ほとんど)常に「偽のウェイクアップのためにループする」という用語が見つかります。 1 このようなウェイクアップを経験された方はいらっしゃるでしょうか(例えばまともなハードウェア/ソフトウェア環境を想定して)?

スプリアス」とは、明らかな理由がないという意味だと思いますが、このような事象が発生する理由は何でしょうか?

( 1 注:ループのやり方に疑問を持っているわけではありません)

編集する お助け質問(コードサンプル好きな人向け)。

以下のようなプログラムがあり、それを実行した場合。

public class Spurious {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition cond = lock.newCondition();
        lock.lock();
        try {
            try {
                cond.await();
                System.out.println("Spurious wakeup!");
            } catch (InterruptedException ex) {
                System.out.println("Just a regular interrupt.");
            }
        } finally {
            lock.unlock();
        }
    }
}

これを起こすにはどうしたらいいのでしょう await ランダムなイベントを永遠に待つことなく、スプリアスを起こすことができますか?

解決方法は?

ウィキペディア spurious wakeupsに関する記事 にはこんな豆知識があります。

<ブロッククオート

pthread_cond_wait() 関数は、Linux では futex システムコールがあります。Linuxの各ブロッキング・システムコールは、突然 EINTR がシグナルを受信したとき。... pthread_cond_wait() の外にいたわずかな時間で本当の目覚めを逃してしまうかもしれないので、待ち時間を再開することはできません。 futex システムコールを使用します。このレースコンディションは、呼び出し元が不変量をチェックすることでしか回避できない。したがって、POSIXシグナルは偽のウェイクアップを発生させます。

概要 : Linuxのプロセスがシグナルを受けた場合、待機中のスレッドはそれぞれ素敵でホットな スプリアスウェイクアップ .

私はそれを買う。よく言われる「パフォーマンスのため」という曖昧な理由よりは、飲み込みやすいと思います。