java - wait/notifyAll 未按预期工作

标签 java multithreading concurrency

我有一个有两种方法的类,一个发送消息,另一个确认消息已被接收/处理

   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/

相关文章:

java - 让 Eclipse Java Organize Imports 与 Google checkstyle 一起使用

java - RxJava : How to group arbitrary large number of items using my own boundary function

java - 为什么我在 String 源代码中看到构造函数,但在 JavaDocs 中却看不到?

java - Android 加载时的多个 Web 服务调用

java - 在 30 秒内处理来自 FTP 服务器的 100 MB 以上文件?

java - 编译时检查或 java.util.ConcurrentModificationException

java - 如何使用 Hibernate 4 调用具有多个输出参数的 MS SQL 存储过程?

multithreading - 为什么 Rust 互斥锁似乎没有给最后想要锁定它的线程锁?

java - 如何在java中的超时值后停止/杀死多个线程

java - 如何在 java servlet 中处理并发