从Session的javadoc中可以看出:
Session对象是用于生成和使用消息的单线程上下文。
所以我理解你不应该同时使用来自两个不同线程的Session对象。我不清楚的是你是否可以使用与其创建的不同的线程中的Session对象(或者像Queue这样的子代)。
在我正在处理的情况下,我正在考虑将我的Session对象放入一个可用会话池中,任何线程都可以借用,使用,并在完成后返回池中。
这是犹太人吗?
(使用ActiveMQ BTW,如果这会影响答案。)
答案 0 :(得分:11)
但阅读规范我现在相信你真的不应该从其他线程访问会话,即使你保证没有并发访问。为我摆动它的javadoc的一点是:
连接启动后, 任何有注册消息的会话 listener(s)专用于该线程 传递信息的控制 它。客户端代码是错误的 使用此会话或其任何一个 另一个组成对象 控制线程。唯一的例外 这是使用会话或 连接关闭方法。
注意明确使用'控制线'和单独输出'close()'是唯一的例外。
他们似乎在说即使您正在使用异步消息(即setMessageListener) - 这意味着您在JMS创建的另一个线程上回调以接收消息 - 您永远不会被允许触摸会话或相关来自任何其他线程的对象,因为会话现在“专用”到JMS传递线程。例如,我认为这意味着你甚至无法从另一个线程调用message.acknowledge()。
话虽如此,我只是注意到我们没有遵守这个限制,并且还没有注意到任何不良影响(使用SonicMQ)。但是当然如果你不遵守标准,所有的赌注都会被取消,所以我想我们需要遵守1线程1会话规则以保证安全。
答案 1 :(得分:11)
我认为the JMS 1.1 spec第4.4节的脚注揭示了一些亮点:
可以使用Session对象或其创建的线程数没有限制。限制是多个线程不应同时使用会话的资源。用户应确保满足此并发限制。最简单的方法是使用一个线程。在异步传送的情况下,使用一个线程在停止模式下进行设置,然后启动异步传送。在更复杂的情况下,用户必须提供显式同步。
通过阅读规范,您可以做的就是确定,只要您正确管理并发。