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?
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 aJmsTemplate
and then safely inject this shared reference into multiple collaborators. To be clear, theJmsTemplate
is stateful, in that it maintains a reference to aConnectionFactory
, 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.