JMS会话及其相关结构(消息,消费者,生产者等)的线程不确定性的确切性质是什么?是仅仅必须序列化对它们的访问,还是仅限于创建线程的访问?
或者它是一种混合情况,可以将创建与使用区分开来,即一个线程只能创建它们,然后另一个线程可以是唯一使用它们的线程?这最后一种可能性似乎与this answer中的声明相矛盾,声明"实际上你不能在不同时间从两个不同的线程中使用它!"
但请考虑ActiveMQ文档中的"Server Side" example code。
Server类具有名为session(类型为Session)和replyProducer(类型为MessageProducer)的数据成员
(实际上,会话成员在两个线程中也使用:一个用于创建replyProducer成员,另一个用于创建消息。)
这个官方示例代码是偶然还是按设计工作的?是否真的可以在一个线程中创建这样的对象,然后安排另一个线程来使用它们?
(注意:在其他消息传递基础结构中,例如Solace,可以指定发生回调的线程,这可以被利用来解决这个"对象的线程关联性"限制,但据我所知,在JMS中没有定义这样的API调用。)
答案 0 :(得分:0)
JMS规范说,除了调用Session.Close()
方法之外,不应跨线程使用会话对象。从技术上讲,如果序列化对Session对象或其子(生产者,消费者等)的访问,则可以跨线程访问Session或其子对象。话虽如此,由于JMS是一个API规范,它的实现因供应商而异。一些供应商可能会严格执行线程关联,而有些可能不会。因此,最好坚持使用JMS规范并相应地编写代码。
答案 1 :(得分:0)
官方答复似乎是第4.4节的注脚。 JMS 1.1 specification第60页的“会话”。
可以使用Session对象或其创建的线程数没有限制。限制是多个线程不应同时使用会话的资源。用户应确保满足此并发限制。最简单的方法是使用一个线程。在异步传送的情况下,使用一个线程在停止模式下进行设置,然后启动异步传送。在更复杂的情况下,用户必须提供显式同步。
当然,特定实现是否遵守这是另一回事。在ActiveMQ示例的情况下,代码是符合的,因为所有入站消息处理都是通过单个异步回调。