2

ActiveMQ 文档指出 Session 和 MessageProducer 对象不是线程安全的。如果我有一组可以产生持久消息的线程,那么如何在知道特定发送操作是否成功的情况下正确地将它们发送到 ActiveMQ?

  1. 每个工作线程都有一个单独的 Session/MessageProducer。
  2. 创建显式的生产者线程集并通过 BlockingQueue 将消息传递给它们(如何确定发送是否成功?)。
  3. 对于前面的案例,使用 Future<> 来获得 ActiveMQ 中持久消息的成功状态。
  4. 只需将每个 MessageProducer.sendMessage() 调用包装在同步块中。

或者,对于这种情况,也许有任何最佳实践。谢谢。

4

1 回答 1

3

访问线程之间的共享会话的一个问题是事务管理,就像您在 2-4 中所说的那样。

如果您在 JMS 会话中执行操作,那么您希望确保知道何时提交或回滚事务。这发生在会话对象上。在同一个会话上提交的多个线程将导致错误。

常见的(例如,如果您查看 Spring 中的 JmsTemplate)是您打开一个新的 Connection/Session/MessageProducer,发送一条消息,然后将它们全部关闭。这是非常低效的,但线程安全。为了解决效率问题,您可以将 ConnectionFactory 包装在 PooledConnectionFactory 中。该池将在需要时将会话/连接借给您的线程,并且当在 Session 上调用 close 时,它​​将被放回池中。这样,您根本不必关心线程安全。在此处阅读有关该主题的更多信息。

当然,如果您要进行一些手动管理,则可以使用方法 1 并为每个线程保存一个 Session。如果您有几个线程发送大量消息,那应该是最有效的方式。

于 2015-02-13T15:29:40.153 回答