小编典典

Java中的虚假唤醒真的发生了吗?

all

看到各种与锁定相关的问题并且(几乎)总是找到“由于虚假唤醒而导致的循环”术语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不永远等待随机事件的情况下虚假地唤醒它?


阅读 68

收藏
2022-06-21

共1个答案

小编典典

维基百科关于虚假唤醒的文章有这个花絮:

pthread_cond_wait()Linux中的功能是使用futex系统调用来实现的。EINTR当进程收到信号时,Linux
上的每个阻塞系统调用都会突然返回。…pthread_cond_wait()无法重新开始等待,因为它可能会在futex系统调用之外的一小段时间内错过真正的唤醒。这种竞争条件只能通过调用者检查不变量来避免。因此,POSIX
信号将产生虚假唤醒。

简介 : 如果一个 Linux 进程收到信号,它的等待线程将享受一个不错的、热的 虚假唤醒

我买它。这比通常给出的通常含糊的“这是为了性能”的原因更容易下咽。

2022-06-21