Java 等待/通知所有未按预期工作
我有一个类,有两个方法,一个发送消息,另一个确认消息已被接收/处理Java 等待/通知所有未按预期工作,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个类,有两个方法,一个发送消息,另一个确认消息已被接收/处理 public void send(OTAHotelAvailRS otaHotelAvailRS) throws Exception { MessageAvailRs messageAvailRs = new MessageAvailRs(); messageMap.put(messageAvailRs.getMessageId(), messageAvailRs); syn
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 thread x 100 req中运行时,有一些消息没有从通知中唤醒
例如,一旦发送了所有消息
messageSend = 100
messageRec = 100
messageWake = 98
并且映射的大小为0,没有重复的MessageID
我已经把箱子缩短了。更复杂
我有一个服务,每次收到请求时,都会调用send方法。此方法不在代码中,它将消息发送到JMS队列,其他服务接收此消息,对其进行处理并向另一个JMSQueue发送响应,然后JMSConsumer读取响应并调用confirm方法
怎么了?你用错了
wait方法应始终处于while循环中,如下所示:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
假设Thread1和Thread2正在等待。Thread3调用notifyAll。Thread1首先唤醒,并使用此条件。对于Thread2,Thread2应该再次检查此条件,如果不满足此条件,Thread2应该进入另一次等待。感谢james large
问题是在等待之前调用notifyAll。解决方案是在收到响应时使用布尔值表示无等待
public void send(OTAHotelAvailRS otaHotelAvailRS) throws Exception {
MessageAvailRs messageAvailRs = new MessageAvailRs();
messageMap.put(messageAvailRs.getMessageId(), messageAvailRs);
synchronized (messageAvailRs) {
messagesSend++;
if (!messageAvailRs.isConfirmed()) {
messageAvailRs.wait();
}
messageWake++;
}
}
public void confirmMessage(String messageId) {
logger.debug("Confirmed message: " + messageId);
MessageAvailRs messageAvailRs = messageMap.remove(messageId);
if (messageAvailRs != null) {
meesageAvailRs.confirm();
synchronized (messageAvailRs) {
messageAvailRs.notifyAll();
messagesReceived++;
}
}
}
public synchronized boolean isConfirmed() {
return confimed;
}
public synchronized confirm() {
cofirmed = true;
}
每条线都做什么?是否有许多线程可能同时调用send和receiveMessage?是的,不同的线程同时调用它们。每次在发球时收到请求时,都会调用send。每次处理消息时,JMS使用者都会调用confirm。我错过了一些与将mesages发送到JMS队列和JMS consumerDamn相关的代码!你是对的。这一定是问题所在。我必须先检查消息是否已收到,然后等待响应。让多线程send在发送消息后确认自己的消息不是简单得多吗?假设发送邮件需要一段时间,您可以使用来清空传出消息队列,这样就不会涉及等待。不存在等待条件。“等待”和“通知”用于同步。如果需要,我建议更改!messageAvailRs.isconfirm为while!正如我在回答中所说,messageAvailRs.isconfirm。