当前位置: 首页 > 面试题库 >

Java中是否会发生虚假唤醒?

师增
2023-03-14
问题内容

看到各种与锁定相关的问题,并且(几乎)总是发现“由于虚假唤醒而引起的循环” 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虚假地唤醒它,而不必永远等待随机事件?


问题答案:

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

简介:如果发出Linux进程信号,则其等待线程将各自享受良好的热虚假唤醒。



 类似资料:
  • 问题内容: Java的Object.wait()警告“虚假唤醒”,但C#的Monitor.wait()似乎根本没有提及。 了解Mono是如何在Linux之上实现的,并且Linux具有虚假的唤醒功能,难道不应该在某个地方对此进行记录吗? 问题答案: Joe Duffy的“Windows并行编程”中提到了这一点(P311-312,P598)。这一点很有趣: 请注意,在以上所有示例中,线程必须对所谓的虚

  • 问题内容: 这是线程正在等待notify()或超时的情况。这里添加了while循环来处理虚假唤醒。 在这种情况下,如何区分虚假唤醒和超时?如果是虚假的唤醒,我需要回去等待。如果超时,我需要退出循环。 我可以轻松识别出notify()的情况,因为我将在notify()调用时将dosleep变量设置为false。 编辑:由于嵌入式项目的要求,我正在使用1.4 Java版本。我无法使用,因为它仅在1.5

  • 问题内容: 我试图说服自己,该子句中采取的操作在函数返回 之前发生 (从内存一致性的角度来看)。从JVM规范,很显然,在一个线程中,程序顺序应该是驱动 之前发生 关系-如果 一个 发生 b 按照程序顺序,然后 一 前发生 b 。 但是,我没有看到任何明确说明最终 会在 返回 之前发生的 东西,是吗?或者,编译器是否可以通过某种方式对子句进行重新排序,因为它只是在记录日志。 激励示例:我有一个线程从

  • 问题内容: 根据我所看到的LINQ的许多示例,我正在使用类似于以下代码的代码创建自己的数据上下文和表: 但是对于每个表(小部件,汽车等),我都会得到警告 字段’TableName’从未分配 。我在Google上找不到任何也存在此问题的人。我不觉得我做错了什么,因为我只是复制从不同地方看到的LINQ示例。那么这个警告是怎么回事呢?它警告我一个真正的问题吗?还是我错过了什么? 问题答案: 是的,他们是

  • 问题内容: 哈罗我已经整天调试了我的代码,但是我看不出哪里出了问题。 我在主线程上使用SerialPortEventListener,在工作线程中,我有一个客户端套接字与服务器通信。由于到达此工作线程之后,我仍然需要在主线程中完成一些总结工作,因此我想创建一个“伪线程”,在主线程中等待,直到从侦听器onEvent方法通知它为止。 但是这个伪线程似乎一直在等待。 我检查了锁定的线程,它们在Runna

  • 问题内容: 我多次问到这个问题。有什么好的答案 问题答案: Java中会不会发生内存泄漏? 答案是,这取决于您正在谈论的是哪种内存泄漏。 经典C / C ++内存泄漏是在应用程序或对象完成使用后忽略时发生的,并且会泄漏。循环引用是这种情况的一个子案例,其中应用程序很难知道何时使用/ ,因此忽略了这样做。相关问题是应用程序在释放对象后使用对象,或尝试释放对象两次。(您可以将后者称为内存泄漏,或者仅是