Java 使用来自不同线程的JMS会话

Java 使用来自不同线程的JMS会话,java,multithreading,jms,Java,Multithreading,Jms,从javadoc for it中可以看出: 会话对象是用于生成和使用消息的单线程上下文 因此,我理解您不应该同时使用来自两个不同线程的会话对象。我不清楚的是,您是否可以使用会话对象(或子对象,如队列)来自与其创建的线程不同的线程 在我正在处理的情况下,我正在考虑将会话对象放入一个可用会话池中,任何线程都可以从该池中借用、使用并在使用完会话后返回该池 这是犹太教的吗 (顺便说一句,如果这会影响答案的话,请使用ActiveMQ。)遗憾的是,JMS文档的编写往往不像我们希望的那样清晰或准确:o( 但是

从javadoc for it中可以看出:

会话对象是用于生成和使用消息的单线程上下文

因此,我理解您不应该同时使用来自两个不同线程的会话对象。我不清楚的是,您是否可以使用会话对象(或子对象,如队列)来自与其创建的线程不同的线程

在我正在处理的情况下,我正在考虑将会话对象放入一个可用会话池中,任何线程都可以从该池中借用、使用并在使用完会话后返回该池

这是犹太教的吗


(顺便说一句,如果这会影响答案的话,请使用ActiveMQ。)

遗憾的是,JMS文档的编写往往不像我们希望的那样清晰或准确:o(

但是在阅读规范时,我现在非常确信你真的不应该从其他线程访问会话,即使你保证没有并发访问

一旦连接启动, 具有已注册消息的任何会话 侦听器专用于线程 将消息传递给 如果客户端代码 使用此会话或其任何 构成对象与其他对象 控制线程。唯一的例外 这是会话或 连接关闭方法

请注意,明确使用“控制线程”和单独使用“close()”作为唯一的例外

他们似乎在说,即使您使用异步消息消费(即setMessageListener)-这意味着您在JMS创建的另一个线程上被回调以接收消息-您永远不允许再次从任何其他线程接触会话或相关对象,因为会话现在“专用”于JMS传递线程。例如,我假设这意味着您甚至无法调用message.acknowledge()从另一个线程


话虽如此,我只是注意到我们没有遵守这一约束,也没有注意到任何不良影响(使用SonicMQ)。但当然,如果你不遵守标准,所有赌注都是无效的,因此我想我们需要遵守单线程单会话规则以保持安全。

我认为第4.4节中的脚注说明了一些问题:

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


通过我对规范的阅读,只要您正确管理并发性,您想做什么就可以了。

本页上的最后一篇文章也支持对线程约束的解释:会话必须限制在您控制的单个线程(用于阻止写/读),或JMS为异步侦听分配的单个线程。=>1)对于并发读/写,必须使用单独的会话。2) 对于并行消费,必须使用多个会话。另请参见注释中的精彩解释,正如T.Rob所说,单线程可以随着时间的推移而改变,只需确保强加一个“发生在之前”关系。您可以通过任何方式添加一个链接到引用规范的页面——哪个版本或包/类javadoc(如果是源代码)?谢谢,完成了。见第60页底部的脚注。