JMS会话单线程意味着什么?

JMS会话单线程意味着什么?,jms,activemq,tibco-ems,Jms,Activemq,Tibco Ems,JMS会话及其相关构造(消息、使用者、生产者等)的线程不安全性的确切性质是什么?只是对它们的访问必须序列化,还是访问仅限于创建线程 或者这是一种混合的情况,在这种情况下,创建和使用可以区分开来,即一个线程只能创建它们,而另一个线程可以是唯一使用它们的线程?最后一种可能性似乎与“事实上,你也不能在不同的时间从两个不同的线程使用它”的说法相矛盾 但请考虑ActudioQ文档。 Server类具有名为session(会话类型)和replyProducer(MessageProducer类型)的数据成员

JMS会话及其相关构造(消息、使用者、生产者等)的线程不安全性的确切性质是什么?只是对它们的访问必须序列化,还是访问仅限于创建线程

或者这是一种混合的情况,在这种情况下,创建和使用可以区分开来,即一个线程只能创建它们,而另一个线程可以是唯一使用它们的线程?最后一种可能性似乎与“事实上,你也不能在不同的时间从两个不同的线程使用它”的说法相矛盾

但请考虑ActudioQ文档。

Server类具有名为session(会话类型)和replyProducer(MessageProducer类型)的数据成员,它们是

  • 在一个线程中创建:无论哪个线程调用Server()构造函数,从而通过实际创建调用调用setupMessageQueueConsumer()方法;及
  • 用于另一个线程:调用onMessage()异步回调的线程
(事实上,会话成员也在两个线程中使用:一个线程用于创建replyProducer成员,另一个线程用于创建消息。)

这个官方示例代码是偶然工作还是设计工作?真的有可能在一个线程中创建这样的对象,然后安排另一个线程使用它们吗


(注意:在其他消息传递基础设施中,如Solace,可以指定发生回调的线程,可以利用该线程绕过“对象的线程关联性”限制,但据我所知,JMS中没有定义此类API调用。)

JMS规范规定,除非调用
session.Close()方法,否则不应跨线程使用会话对象。从技术上讲,如果对会话对象或其子对象(生产者、消费者等)的访问是序列化的,则可以跨线程访问会话或其子对象。话虽如此,由于JMS是一种API规范,它的实现因供应商而异。有些供应商可能会严格执行线程关联,而有些供应商可能不会。因此,最好还是坚持JMS规范并相应地编写代码。

官方答案似乎是第4.4节的脚注。第60页的“会议”

对于可以使用会话对象或其创建的会话对象的线程数没有限制。限制是一个会话的资源不应该被多个线程同时使用。由用户确保满足此并发限制。最简单的方法是使用一个线程。在异步传递的情况下,在停止模式下使用一个线程进行设置,然后启动异步传递。在更复杂的情况下,用户必须提供显式同步


当然,特定的实现是否遵守这一点是另一回事。在ActiveMQ示例中,代码是一致的,因为所有入站消息处理都是通过单个异步回调进行的

那么,ActiveMQ文档中的示例代码是出于偶然还是出于设计?换句话说,它是符合JMS规范还是不符合JMS规范?在我看来,它不符合JMS规范。