How to understand the "synchronous" and "asynchronouns" messaging in JMS?

Freewind picture Freewind · Feb 28, 2014 · Viewed 21.6k times · Source

After reading some document of JMS, I totally puzzled by the phrase synchronous and asynchronouns.

See this page: http://docs.oracle.com/cd/E19798-01/821-1841/bncdq/index.html

Synchronous

You use the receive method to consume a message synchronously. You can use this method at any time after you call the start method:

connection.start();
Message m = consumer.receive();
connection.start();
Message m = consumer.receive(1000); // time out after a second

To consume a message asynchronously, you use a message listener, described in the next section.

Asynchronous

JMS Message Listeners A message listener is an object that acts as an asynchronous event handler for messages. This object implements the MessageListener interface, which contains one method, onMessage. In the onMessage method, you define the actions to be taken when a message arrives.

You register the message listener with a specific MessageConsumer by using the setMessageListener method. For example, if you define a class named Listener that implements the MessageListener interface, you can register the message listener as follows:

Listener myListener = new Listener();
consumer.setMessageListener(myListener);

I have two questions:

  1. As what I understood, the nature of JMS is asynchronous. Producer publishes messages to the queue/topic, it doesn't need to wait consumer. This is asynchronous behaviour. How can it be "synchronous"?

  2. If the "mesageListener" is asynchronous, but in my test with spring-jms, I found it always running in a thread. That means, if I write Thread.sleep(2000) in onMessage, it have to be wait 2 seconds before processing next message. Is it "asynchronous"?

Answer

JB Nizet picture JB Nizet · Feb 28, 2014

If you understand it better like this, consumer.receive() uses a pull model: you read from a queue and are blocked waiting for this message until it comes, or some timeout has elapsed.

Using a listener uses a push model: you register a listener and, when a message comes in, the listener is called, in a separate thread.

Everything is done in a thread in Java, and the listener call is no exception. Whether the listener message handling prevents the processing of other messages in the queue depends on how many threads are dedicated to message processing. If you configure Spring to use a pool of 5 threads to process messages asynchronously, then 5 listeners will be able to process messages in parallel.