有几个消费者线程在一个信号量上等待异步到达的数据,由单个生产者线程提供。如果消费者已经获取了信号量,生产者如何获取信号量通知他们?在这里,它被阻止并且无法执行 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();
}
当然,删除“同步”会导致
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
同样,生产者线程被阻塞,无法获取信号量来通知消费者。
更新:我应该提到第二次数据准备好时失败。第一次数据准备好时,生产者没有阻塞。下次生产数据时,生产者被阻止。代码中有两个地方生产者执行 notifyAll() 但我在这里只显示一个地方。
更新 2:不幸的是,我无法将程序简化为SSCCE,因为我不明白问题到底出在哪里——此外,这些实际上是 JavaFX 服务,而不是普通线程。
我将所有不相关的代码移出同步块。我使用 jstack 来获取线程转储和 TDA 来查看它。它报告有 2 个监视器(在其他不相关的监视器中)。其中一个是包含数据的 StringBuffer,另一个是类本身。但是它没有报告任何等待线程。我已经使类的一种方法同步,现在我删除了关键字。线程争用似乎已经消失。
顺便说一句,receiveSemaphore 只是一个 Object - 一个通用信号量,而不是 java.util.Semaphore 类。