如果消息不包含消息选择器条件,为什么消费者停止了?

时间:2019-04-18 14:33:42

标签: java jms

我最近与jms合作,并且有这样一个问题。我必须收到消息1)所有消息2)仅类型='LIQUID'的地方。我创建了两个消费者

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue(QUEUE_FOR_RECEIVED);
        QueueBrowser queueBrowser = session.createBrowser(queue);
        Enumeration enumeration = queueBrowser.getEnumeration();
        MessageConsumer consumer = session.createConsumer(queue);
        MessageConsumer liquidConsumer = session.createConsumer(queue, "type = 'LIQUID'");

首先收到所有邮件,仅收到type = 'LIQUID'。但是,如果消息不包含type='LIQUID'

,第二个使用者就停止了应用程序
while (enumeration.hasMoreElements()) {
            ObjectMessage ss = (ObjectMessage) consumer.receive();
            System.out.println(ss.getObject());
            ObjectMessage msg = (ObjectMessage) liquidConsumer.receive(); // here consumer stopped if message doesn't contain type ='LIQUID'
            System.out.println(msg.getObject());
            enumeration.nextElement();
        }

如何改进?

1 个答案:

答案 0 :(得分:1)

应用程序停止的原因是因为javax.jms.MessageConsumer.receive() blocking 调用。换句话说,它将阻止进一步执行,直到返回结果。如果队列中没有包含与选择器匹配的任何消息,则对javax.jms.MessageConsumer.receive()的调用将无限期地阻塞。这是预期的,已记录的行为。

如果您不想在这里无限期封锁,可以:

  1. 异步接收消息(例如,使用javax.jms.MessageListener实现)
  2. 使用javax.jms.MessageConsumer.receive(int)并将超时传递给receive,以便在给定超时后仍未收到消息的情况下返回呼叫。
  3. 使用javax.jms.MessageConsumer.receiveNoWait(),它将尝试接收下一条匹配的消息,如果没有立即可用的匹配消息,它将返回。