[rabbitmq-discuss] Channel thread safety in Java client

Jiri Krutil jiri at krutil.com
Tue Jul 5 13:24:08 BST 2011


thanks for that detailed explanation, it definitely helps.

The concept of customizable thread pool and executor you describe sounds
nice. I guess it will be easier and more natural to program against such

The reason I'm interested in how this works is that I'm trying to put
together a vendor-neutral AMQP C++ API with support for async
consumption and I find a lot of inspiration for that in the Java client.

My initial goal is to find a feature set and semantics that can be
mapped to RabbitMQ and Qpid. The API should expose features common for
0-9-1 and 0-10 specs; I'm kind of ignoring AMQP 1.0 for now.

I already have a draft implementation of this API for Qpid 0.7 C++
client. Still not sure if rabbitmq-c has everything I need...


> Jiri,
> The current implementation of the Java Client calls the Consumer
> interface on the same thread that the Channel work is done on.  This
> means that anything done in the Consumer callbacks is synchronised
> with all the other channel stuff going on, and could potentially block
> it.  There are notes on the api-guide pages to warn you about this.
> The QueueingConsumer class basically makes sure that the Consumer
> callbacks do not cause any problems, putting the messages on the
> (dedicated) queue for any (usually the main) thread to access them.
> This means that, even though there may be many consumers defined for a
> Channel, ownership of the Channel is not passed to the 'lib's
> connection thread', and you can continue to use the Channel from the
> main thread, or whatever thread you have allocated to run it from.
>  You can ack messages, and anything else you want, too.
> The thing you shouldn't do is to call Channel methods (for the same
> channel) from more than one thread at a time.  This is because the
> threading model in the channel is 'challenged'.
> We are currently working on the Consumer and Channel threading
> restrictions -- we want to run all the Consumer callbacks on a thread
> which is distinct from the Connection thread; and allow channels to be
> driven from multiple threads.  This would mean it is feasible to do
> most Channel operations from the Consumer callback itself, and from
> any other thread.
> Incidentally, the way our changes are going at the moment, we will
> expose the execution thread pool for Consumer callbacks; and allow the
> user to have control over how many threads are allocated.  For
> example, it might be thought sensible to have a single thread per
> channel allocated for Consumer callbacks; but this could mean a large
> penalty for a large number of channels that may be doing very little
> work.  Instead we pass work to an Executor (managed so that all the
> work required by a single channel is serialised) which runs it on a
> thread from a pool.  The default Executor will use a (fixed) pool of
> 16 threads, but the interface will allow passing in any Executor
> implementation for the Connection.
> I hope this helps.  Feedback is welcome.
> Steve Powell  (a happy bunny)

More information about the rabbitmq-discuss mailing list