Our application, running in a WebLogic 12c, is retrieving messages from a queuing system, where the queue we are retrieving messages from is configured as a FIFO. We are using Spring to configure the retrieval functionality and both the container (org.springframework.jms.listener.DefaultMessageListenerContainer) and the messages listener (org.springframework.jms.core.support.JmsGatewaySupport) are singletons. Furthermore, that container has configured a WorkManager by default as task executor. To guarantee that the messages are processed in the expected order (the order how they are sent to the queue), we use a ReentrantLock in the listener, and we were expecting that messages were retrieved and processed one by one. The listener code is the following one:
public class JmsReceiveAdapterImpl extends JmsGatewaySupport implements SessionAwareMessageListener {
private final ReentrantLock lock = new ReentrantLock(true);
[...]
public void onMessage(Message rcvMessage, Session session) throws JMSException {
lock.lock();
logger.warn("Lock has been acquired by thread: " + Thread.currentThread().getId());
try {
[...]
} finally {
logger.warn("Lock is going to be released by thread: " + Thread.currentThread().getId());
lock.unlock();
}
}
}
Even though two messages are placed on the queue in the correct order, and they are consumed in that order (recall that the queue is a FIFO one), somehow the two message are processed in parallel by the application as it is shown in the following log chunk:
Lock has been acquired by thread: 28 Backout count: 1 Message 1 / 1 received from XXX Message ID1 received. Lock has been acquired by thread: 54 Backout count: 1 Message 1 / 1 received from XXX Message ID2 received. ***** ERROR ***** Lock is going to be released by thread: 54 Lock is going to be released by thread: 28
Why are we obtaining this behaviour? Any idea?
Thank you so much in advanced.
Change
To
What you are going to probably see is that the
System.identityHashCode
will be two different numbers. If it were the same object the identityHashCode would be identical. If they are different, that means they are different objects.What that tells you is that there are more than one
ReentrantLock
instance and will not support mutual exclusion on the difference instances.