【发布时间】:2018-04-26 12:58:36
【问题描述】:
我有一个类有两个方法,一个发送消息,另一个确认消息已被接收/处理
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,没有重复的messageIds。
我已经缩短了案例。它更复杂。
我有一项服务,每次收到请求时都会调用 send 方法。该方法(不在代码中)将消息发送到 JMS Queue,其他服务接收此消息,处理它们并向另一个 JMSQueue 发送响应,然后 JMSConsumer 读取响应并调用确认方法。
怎么了?
【问题讨论】:
-
每个线程的作用是什么?是否有多个线程可能同时调用 send 和 receiveMessage?
-
是的,它们被不同的线程同时调用。每次在服务器上收到请求时都会调用发送。每次处理消息时,JMS 使用者都会调用确认。我错过了一些与将消息发送到 JMS 队列和 JMS 消费者相关的代码
-
该死!你说的对。这一定是问题所在。我必须检查是否已经收到消息以等待响应。
-
拥有一个多线程的
send,在发送消息后确认自己的消息不是更简单吗?假设发送东西需要时间,您可以使用Executor 清空传出消息队列,并且不会涉及等待。
标签: java multithreading concurrency