我有一个有两种方法的类,一个发送消息,另一个确认消息已被接收/处理
public void send(OTAHotelAvailRS otaHotelAvailRS) throws Exception {
MessageAvailRs messageAvailRs = new MessageAvailRs();
messageMap.put(messageAvailRs.getMessageId(), messageAvailRs);
synchronized (messageAvailRs) {
messagesSend++;
messageAvailRs.wait();
messageWake++;
}
}
public void confirmMessage(String messageId) {
logger.debug("Confirmed message: " + messageId);
MessageAvailRs messageAvailRs = messageMap.remove(messageId);
if (messageAvailRs != null) {
synchronized (messageAvailRs) {
messageAvailRs.notifyAll();
messagesReceived++;
}
}
}
在多线程环境(3 线程 x 100 请求)中运行时,有些消息不会从通知中唤醒。
例如,一旦所有消息均已发送
messageSend = 100
messageRec = 100
messageWake = 98
并且 map 大小为0,没有重复的messageId。
我已经缩短了案例。情况比较复杂。
我有一项服务,每次收到请求时都会调用发送方法。此方法(不在代码中)将消息发送到 JMS 队列,其他服务接收此消息,处理它们并将响应发送到另一个 JMSQueue,然后 JMSConsumer 读取响应并调用确认方法。
出了什么问题?
最佳答案
您正在使用wait()
错。
wait
方法应该始终处于 while 循环中,如下所示:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
假设Thread1和Thread2正在等待。 Thread3 调用notifyAll
。 Thread1 首先醒来,并消耗此条件。当谈到 Thread2 时,Thread2 应该再次检查这个条件,如果不满足,Thread2 应该陷入另一个等待
。
关于java - wait/notifyAll 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50043625/