ActiveMQ线程安全吗?

4
我们希望在同一进程的不同线程上运行cms::MessageConsumercms::MessageProducer
如何安全地实现这一点?
是否需要使用两个cms::Connection对象和两个cms::Session对象,分别用于消费者和生产者,以保证安全?这是必要的吗?
在静态库级别是否存在对象之间的共享状态会阻止这种类型的使用?
3个回答

6
您应该阅读JMS v1.1规范,其中清楚地指出哪些对象可以在多个线程中使用,哪些不行。Session、MessageConsumer和MessageProducer被认为是不安全的,在多个线程之间共享它们通常会造成麻烦。我们通常尽力使它们线程安全,但肯定有一些方法可以让您陷入麻烦。通常最好在每个线程中使用单个session,并且通常最好为每个MessageConsumer / MessageProducer使用一个session,因为Session包含一个单个调度线程,这意味着具有许多消费者的会话必须共享其调度线程以将消息发送到每个消费者,这可能会降低延迟,具体取决于情况。

请澄清最后一句话。 - ThomasMcLeod
添加了一些内容,其中许多已经在博客文章和规范中公开,因此我不会在这里重复。 - Tim Bish

5
我回答自己的问题,补充Tim Bish的答案,我接受他提供的基本信息。
来自http://activemq.apache.org/cms/cms-api-overview.html

什么是CMS?
CMS API是Java中JMS API的C ++对应项,用于从网络上分散的客户端或位于同一台计算机上的客户端发送和接收消息。在CMS中,我们尽力保持与JMS API的相似性,仅在JMS功能强烈依赖于Java编程语言本身的功能时才会有所偏离。即使存在一些差异,大多数差异都很小,并且在很大程度上CMS遵守JMS规范,因此深入了解JMS的工作原理应该可以更轻松地使用CMS。

JMS规范对线程安全有什么要求?

在此下载规范: http://download.oracle.com/otndocs/jcp/7195-jms-1.1-fr-spec-oth-JSpec/

2.8 多线程 JMS 可能要求其所有对象都支持并发使用。由于支持并发访问通常会增加一些开销和复杂性,因此 JMS 设计将其对并发访问的要求限制在那些自然会被多线程客户端共享的对象上。其他对象设计为一次只能由一个逻辑控制线程访问。JMS 定义了一些特定规则来限制会话的并发使用。由于它们需要比我们在这里展示的更多的 JMS 具体知识,所以稍后会进行描述。在这里,我们将描述实施它们的原因。
表 2-2 JMS 支持并发使用的对象:
- Destination:是 - ConnectionFactory:是 - Connection:是 - Session:否 - MessageProducer:否 - MessageConsumer:否
限制对会话的并发访问有两个原因。首先,会话是支持事务的 JMS 实体。很难实现多线程事务。其次,会话支持异步消息消费。重要的是,JMS 不要求用于异步消息消费的客户端代码能够处理多个并发消息。此外,如果会话已设置为具有多个异步消费者,则重要的是客户端不被迫处理这些单独消费者同时执行的情况。这些限制使得 JMS 更易于典型客户端使用。更复杂的客户端可以通过使用多个会话来获得所需的并发性。

2
据我所知,从Java方面来看,连接是线程安全的(而且创建起来相当昂贵),但会话消息生产者不是线程安全的。因此,似乎您应该为每个线程创建一个会话。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接