当前位置: 首页 > 知识库问答 >
问题:

如何获取信号量以通知该信号量上的等待线程?(Java)

颜德馨
2023-03-14

有几个消费者线程在等待由单个生产者线程提供的异步到达的数据的信号量。如果消费者已经获取了信号量,生产者如何获取信号量来通知他们呢?在这里,它被阻塞了,不能执行notifyAll()

 Object receiveSemaphore = new Object();

// consumer threads
synchronized (receiveSemaphore) {
    while (!dataIsReady) {
        try {
            receiveSemaphore.wait();
        } catch (InterruptedException e) {
        }
    }
}

// producer thread          
synchronized (receiveSemaphore) {
    dataIsReady = true;
    receiveSemaphore.notifyAll();
}

当然,删除“synchronized”会导致

java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)

同样,生产者线程被阻塞,无法获取信号量来通知消费者。

更新:我应该提到,这在第二次数据准备就绪时失败。第一次数据准备就绪时,生产者没有阻塞。下一次产生数据时,生产者阻塞了。代码中也有两个地方生产者做了一个通知所有(),但我在这里只显示为一个地方。

更新2:不幸的是,我无法将程序简化为SSCCE,因为我不明白问题到底在哪里——此外,这些实际上是JavaFX服务,而不是普通线程。

我将所有不相关的代码移出同步块。我使用jstack获取线程转储,并使用TDA查看它。据报道,有2名监督员(其他无关监督员)。其中一个是包含数据的StringBuffer,另一个是类本身。然而,它没有报告任何等待线程。我已经使类的一个方法同步,现在我删除了关键字。线程争用似乎已经结束。

顺便说一下,receiveSemaphore只是一个对象——一个通用信号量,而不是java.util.Semaphore类。

共有1个答案

公羊俭
2023-03-14

不幸的是,我无法将程序简化为SSCCE,因为我不知道问题的确切位置-此外,这些实际上是JavaFX服务,而不是普通线程

我将所有不相关的代码移出了同步块。我使用 jstack 来获取线程转储和 TDA 来查看它。它报告说有2个监视器(在其他不相关的监视器中)。其中一个是包含数据的 StringBuffer,另一个是类本身。但是,它没有报告任何等待线程。我已经同步了类的一种方法,现在我删除了关键字。线程争用似乎已经消失。

顺便说一下,receiveSemaphore只是一个对象——一个通用信号量,而不是java.util.Semaphore类。

 类似资料:
  • 问题内容: 我有一个整数片,它们是同时操作的: 我使用缓冲通道作为信号灯,以使并发运行go例程的上限: 上面的代码在到达最后两个整数或最后两个整数之前都可以很好地工作,因为程序在这些最后执行例程完成之前就结束了。 问题 :如何等待缓冲的通道耗尽? 问题答案: 您不能以这种方式使用信号灯(在这种情况下为通道)。不能保证在处理值和调度更多goroutine时,它永远不会为空。在这种情况下,这尤其不重要

  • 我是否应该有两个生命线,每个线程一个,即使它们在类的同一个实例上操作?我的建模工具(Enterprise Architect12)不允许同一个类在序列图上出现两次,所以似乎不鼓励这样做。 编辑:Geert已经注意到序列图应该使用实例,而不是类,这是一个公平的评论。然而,问题是相同的:多条生命线意味着多个实例,但在问题中,和只是从不同的线程操作同一个实例。那怎么代表呢?

  • 我们有一个限制实现,基本上可以归结为: 我想收集关于信号量对方法的整体响应时间的影响的指标。例如,我想知道等待获取的线程数量,等待的时间等等。我想,我正在寻找的是一种也能捕捉时间信息的量规。 如何测量Semphore统计数据?

  • 首先想到的问题是,为什么我们需要信号量? 一个简单的答案,以保护多个进程共享的关键/共同区域。 假设多个进程正在使用相同的代码区域,如果所有人都想并行访问,那么结果是重叠的。 例如,多个用户仅使用一台打印机(通用/关键部分),例如个用户,同时给予个作业,如果所有作业并行启动,则一个用户输出与另一个用户输出重叠。 因此,我们需要使用信号量来保护这个信号,即当一个进程正在运行时锁定关键部分,并在完成时

  • 信号量 信号量是一种同步互斥机制的实现,普遍存在于现在的各种操作系统内核里。相对于spinlock 的应用对象,信号量的应用对象是在临界区中运行的时间较长的进程。等待信号量的进程需要睡眠来减少占用 CPU 的开销。参考教科书“Operating Systems Internals and Design Principles”第五章“同步互斥”中对信号量实现的原理性描述: struct semaph

  • 一个线程发送信号量,另外一个线程接收信号量 一个线程发送信号量,另外一个线程接收信号量 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie