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

Eva*_*van 13 java multithreading jms

Session的javadoc中可以看出:

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

所以,我明白,你不应该使用一个会话对象,从两个不同的线程在同一时间.我不清楚的是,你是否可以从与其创建的不同的线程中使用Session对象(或者像Queue这样的子代).

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

这是犹太人吗?

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

Ben*_*ler 11

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

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

连接启动后,任何具有已注册消息侦听器的会话都专用于向其传递消息的控制线程.客户端代码使用此会话或来自另一个控制线程的任何组成对象是错误的.唯一的例外是使用会话或连接关闭方法.

注意清楚使用'控制线'和单独输出'close()'是唯一的例外.

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

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


T.R*_*Rob 11

我认为JMS 1.1规范第4.4节的脚注有一些亮点:

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

通过我阅读规范你想要做的就是OK,只要你正确地管理并发.