RECEIVE_TIMEOUT_NO_WAIT 的 JmsTemplate 不从 JMS 队列中检索消息

JmsTemplate with RECEIVE_TIMEOUT_NO_WAIT doesn't retrieve messages from JMS queue

鉴于我有 ActiveMQ 队列,其中已经存在许多消息。

当我将 JmsTemplate 上的接收超时设置为 RECEIVE_TIMEOUT_NO_WAIT 时,它等于 -1:

jmsTemplate.setReceiveTimeout(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); 

并尝试接收其中一条消息:

Message msg = jmsTemplate.receive(queueName);

那么msg就是null,但是根据JavaDoc不应该是:

/**
 * Timeout value indicating that a receive operation should
 * check if a message is immediately available without blocking.
 */
public static final long RECEIVE_TIMEOUT_NO_WAIT = -1;

这是为什么?

当我这样做时:

jmsTemplate.setReceiveTimeout(1000);

然后检索消息。

它与 JmsTemplate 完全无关,因为它只是委托给底层 JMS Consumer 对象:

protected Message receiveFromConsumer(MessageConsumer consumer, long timeout) throws JMSException {
    if (timeout > 0) {
        return consumer.receive(timeout);
    }
    else if (timeout < 0) {
        return consumer.receiveNoWait();
    }
    else {
        return consumer.receive();
    }
}

我会说它的工作方式完全符合 JMS 设计者的预期:

/** Receives the next message if one is immediately available.
  *
  * @return the next message produced for this message consumer, or 
  * null if one is not available
  *  
  * @exception JMSException if the JMS provider fails to receive the next
  *                         message due to some internal error.
  */ 

Message receiveNoWait() throws JMSException;

换句话说,它适用于您绝对不想在任何时候阻塞线程的用例,如果当前没有消息已被代理发送给消费者 -甚至不等待网络 I/O 完成,这正是 ActiveMQ 实现它的方式 - 启动 I/O 但 returns null 如果 I/O 没有立即完成(如果涉及网络,很可能就是这种情况。