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

标签 java multithreading locking spurious-wakeup

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

最佳答案

维基百科 article on spurious wakeups有这个花絮:

The pthread_cond_wait() function in Linux is implemented using the futex system call. Each blocking system call on Linux returns abruptly with EINTR when the process receives a signal. ... pthread_cond_wait() can't restart the waiting because it may miss a real wakeup in the little time it was outside the futex system call. This race condition can only be avoided by the caller checking for an invariant. A POSIX signal will therefore generate a spurious wakeup.

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

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

关于java - Java中的虚假唤醒真的发生了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1050592/

相关文章:

java - 在run方法中,如何找到start是从哪里调用的?

java - org.apache.commons.io.IOUtils.toByteArray 的 Android 等价物

multithreading - Kotlin:使用非阻塞I/O阻塞协程

c# - 应用程序在 Dispatcher.Invoke 后卡住

java - 在 Java 方法中传递许多字符串

java - 表单输入文件的 Spring 注释验证

C信号量线程读取文件

mysql - 如何正确错开数以千计的插入以免锁定表?

iis - 无法删除文件,IIS锁定

python - 我什么时候会获取 block 状态设置为 False 的锁?