views:

145

answers:

3

From the javadoc for Session it states:

A Session object is a single-threaded context for producing and consuming messages.

So I understand that you shouldn't use a Session object from two different threads at the same time. What I'm unclear on is if you could use the Session object (or children such as a Queue) from a different thread than the one it created.

In the case I'm working on, I'm considering putting my Session objects into a pool of available sessions that any thread could borrow from, use, and return to the pool when it is finished with it.

Is this kosher?

(Using ActiveMQ BTW, if that impacts the answer at all.)

A: 

Why not, you can I believe. And in that case you will get two different session objects. Where is the problem?

AFA, pooling of session object is concern. I don't see the point. Here you are supposing that there would be a single object. Then pool, what for. Further, session object is not suppose to be heavy to instantiate one, thus I don't see why we should go that way. My 2 cents.

Adeel Ansari
A: 

Sadly the JMS docs are often not written as clearly or precisely as we might like :o(

But reading the spec I'm now pretty convinced you really shouldn't access the session from other threads, even if you guarantee there's no concurrent access. The bit of the javadoc that swung it for me was:

Once a connection has been started, any session with a registered message listener(s) is dedicated to the thread of control that delivers messages to it. It is erroneous for client code to use this session or any of its constituent objects from another thread of control. The only exception to this is the use of the session or connection close method.

Note the clear use of 'thread of control' and the singling out of 'close()' as the only exception.

They seem to be saying that even if you're using asynchronous message consumption (i.e. setMessageListener) - which means you get called back on another thread created by JMS to receive messages - you're never allowed to touch the session or related objects again from any other thread, because the session is now 'dedicated' to the JMS delivery thread. For example, I assume this means you couldn't even call message.acknowledge() from another thread.

Having said that, I only just noticed that we haven't been obeying this constraint, and have yet to notice any ill effects (using SonicMQ). But of course if you don't obey the standard, all bets are off, so I guess we need to obey the 1-thread 1-session rule to stay safe.

Ben Spiller
The last post on this page also backs up this interpretation of the threading constraints: http://stackoverflow.com/questions/1669746/jms-acknowledge-asynchronous-message
Ben Spiller
A: 

I think the footnote from section 4.4 in the spec sheds some light:

There are no restrictions on the number of threads that can use a Session object or those it creates. The restriction is that the resources of a Session should not be used concurrently by multiple threads. It is up to the user to insure that this concurrency restriction is met. The simplest way to do this is to use one thread. In the case of asynchronous delivery, use one thread for setup in stopped mode and then start asynchronous delivery. In more complex cases the user must provide explicit synchronization.

By my reading of the spec what you want to do is OK, provided you correctly manage concurrency.

T.Rob