gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 11:31:51 29 4
gpt4 key购买 nike

有多个消费者线程在信号量上等待异步到达的数据,这些数据由单个生产者线程提供。如果消费者已经抢到了信号量,生产者如何获取信号量来通知他们呢?在这里,它被阻塞了,不能做一个 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)

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

更新:我应该提一下,第二次数据准备就绪时失败了。第一次数据准备好,生产者没有阻塞。下一次产生数据时,生产者阻塞。此外,生产者在代码中有两个地方执行了 notifyAll(),但我在这里仅将其显示为一个地方。

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

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

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

最佳答案

不幸的是,我无法将程序缩减为 SSCCE,因为我不明白问题到底出在哪里 - 此外,这些实际上是 JavaFX 服务,而不是普通线程。

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

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

关于java - 如何获取信号量以通知该信号量上的等待线程? ( java ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16967428/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com