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

时间:2010-03-22 08:05:54

标签: java multithreading jms

Session的javadoc中可以看出:

  

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

所以我理解你不应该同时使用来自两个不同线程的Session对象。我不清楚的是你是否可以使用与其创建的不同的线程中的Session对象(或者像Queue这样的子代)。

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

这是犹太人吗?

(使用ActiveMQ BTW,如果这会影响答案。)

2 个答案:

答案 0 :(得分:11)

遗憾的是,JMS文档通常不像我们所希望的那样清晰或精确地编写:o(

但阅读规范我现在相信你真的不应该从其他线程访问会话,即使你保证没有并发访问。为我摆动它的javadoc的一点是:

  

连接启动后,   任何有注册消息的会话   listener(s)专用于该线程   传递信息的控制   它。客户端代码是错误的   使用此会话或其任何一个   另一个组成对象   控制线程。唯一的例外   这是使用会话或   连接关闭方法。

注意明确使用'控制线'和单独输出'close()'是唯一的例外。

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

话虽如此,我只是注意到我们没有遵守这个限制,并且还没有注意到任何不良影响(使用SonicMQ)。但是当然如果你不遵守标准,所有的赌注都会被取消,所以我想我们需要遵守1线程1会话规则以保证安全。

答案 1 :(得分:11)

我认为the JMS 1.1 spec第4.4节的脚注揭示了一些亮点:

  

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

通过阅读规范,您可以做的就是确定,只要您正确管理并发。