Search code examples
javajmsactivemq-classic

Is this way of sending messages to a queue thread-safe?


I am using an instance of JmsTemplate from Spring 4.3.30 to write messages to a message queue. The code looks like this:

public void sendObjectMessage(final Serializable msg, final Long scheduledDelaySeconds) {
    try {
        this.jmsTemplate.send(this.queue, new MessageCreator() {
            public Message createMessage(final Session session) throws JMSException {
                Message m = session.createObjectMessage(msg);
                if (scheduledDelaySeconds != null){
                    m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 1000 * scheduledDelaySeconds);
                }
                return m;
            }
        });
    } catch (Exception e) {
        Logging.logError("Error sending MQ object message", e);
    }
}

Also, in the code above this.queue is an instance of

org.apache.activemq.command.ActiveMQQueue

So I wonder if this usage of this.jmsTemplate and of this.queue is thread safe.

What will happen if this code is called simultaneously within multiple threads (while using these shared instances of the JmsTemplate and of the queue)? Could that cause any problems?


Solution

  • You shouldn't have any problems.

    As noted in the Spring documentation:

    Instances of the JmsTemplate class are thread-safe once configured. This is important because it means that you can configure a single instance of a JmsTemplate and then safely inject this shared reference into multiple collaborators. To be clear, the JmsTemplate is stateful, in that it maintains a reference to a ConnectionFactory, but this state is not conversational state.

    Also, a JMS destination (e.g. ActiveMQQueue which extends ActiveMQDestination which implements javax.jms.Destination) is one of the few thread-safe objects in JMS. From the JavaDoc:

    Destination objects support concurrent use.