Вопрос

We would like to run our cms::MessageConsumer and cms::MessageProducer on different threads of the same process.

How do we do this safely?

Would having two cms::Connection objects and two cms::Session objects, one each for consumer and producer, be sufficient to guarantee safety? Is this necessary?

Is there shared state between objects at the static library level that would prevent this type of usage?

Это было полезно?

Решение

You should read the JMS v1.1 specification, it calls out clearly which objects are valid to use in multiple threads and which are not. Namely the Session, MessageConsumer and MessageProducer are considered unsafe to share amongst threads. We generally try to make them as thread safe as we can but there are certainly ways in which you can get yourself into trouble. Its generally a good idea to use a single session in each thread and in general its a good idea to use a session for each MessageConsumer / MessageProducer since the Session contains a single dispatch thread which means that a session with many consumers must share its dispatch thread for sending messages on to each consumer which can lower latency depending on the scenario.

Другие советы

I'm answering my own question to supplement Tim Bish's answer, which I am accepting as having provided the essential pieces of information.

From http://activemq.apache.org/cms/cms-api-overview.html

What is CMS?

The CMS API is a C++ corollary to the JMS API in Java which is used to send and receive messages from clients spread out across a network or located on the same machine. In CMS we've made every attempt to maintain as much parity with the JMS api as possible, diverging only when a JMS feature depended strongly on features in the Java programming language itself. Even though there are some differences most are quite minor and for the most part CMS adheres to the JMS spec, so having a firm grasp on how JMS works should make using CMS that much easier.

What does the JMS spec say about thread safety?

Download spec here: http://download.oracle.com/otndocs/jcp/7195-jms-1.1-fr-spec-oth-JSpec/

2.8 Multithreading JMS could have required that all its objects support concurrent use. Since support for concurrent access typically adds some overhead and complexity, the JMS design restricts its requirement for concurrent access to those objects that would naturally be shared by a multithreaded client. The remainder are designed to be accessed by one logical thread of control at a time. JMS defines some specific rules that restrict the concurrent use of Sessions. Since they require more knowledge of JMS specifics than we have presented at

Table 2-2 JMS Objects that Support Concurrent Use

  • Destination: YES
  • ConnectionFactory: YES
  • Connection: YES
  • Session: NO
  • MessageProducer: NO
  • MessageConsumer: NO

this point, they will be described later. Here we will describe the rationale for imposing them.

There are two reasons for restricting concurrent access to Sessions. First, Sessions are the JMS entity that supports transactions. It is very difficult to implement transactions that are multithreaded. Second, Sessions support asynchronous message consumption. It is important that JMS not require that client code used for asynchronous message consumption be capable of handling multiple, concurrent messages. In addition, if a Session has been set up with multiple, asynchronous consumers, it is important that the client is not forced to handle the case where these separate consumers are concurrently executing. These restrictions make JMS easier to use for typical clients. More sophisticated clients can get the concurrency they desire by using multiple sessions.

As far as I know from the Java side, the connection is thread safe (and rather expensive to create) but Session and messageProducer are not thread safe. Therefore it seems you should create a Session for each of your threads.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top