我们的应用程序运行在WebLogic 12c中,它正在从排队系统中检索消息,其中我们检索消息的队列被配置为FIFO。我们使用Spring来配置检索功能,并且容器(org.springframework.jms.listener.DefaultMessageListenerContainer)和消息监听器(org.springframework.jms.core.support.JmsGatewaySupport)都是单例。此外,该容器默认将工作管理器配置为任务执行程序。为了保证消息按照预期的顺序处理(它们被发送到队列的顺序),我们在监听器中使用ReentrantLock,并且我们期望消息被逐个检索和处理。听者代码是下列之一:线程获取已被其他线程获取的ReentrantLock
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();
}
}
}
即使两个消息被放置在队列中以正确的顺序,它们被消耗的顺序(召回该队列是一个FIFO之一),以某种方式在两个消息由应用程序并行处理,如以下日志块所示:
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
为什么我们要获得此行为?任何想法?
非常感谢你的进步。
考虑到'ReentrantLock'不工作的机会接近零,我建议你输出'this'到日志,以确保你的班级是一个单身人士。 – user3707125
同时检查你是否在这个锁创建的某些条件下不调用'await()'。 – talex
如果你想绝对确定,你可以将锁定为静态,但是从设计的角度来看,这将是一场灾难 –