Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程获取其他线程已经获取的ReentrantLock_Java_Multithreading_Reentrantlock - Fatal编程技术网

Java 线程获取其他线程已经获取的ReentrantLock

Java 线程获取其他线程已经获取的ReentrantLock,java,multithreading,reentrantlock,Java,Multithreading,Reentrantlock,我们的应用程序运行在WebLogic 12c中,正在从队列系统中检索消息,我们从中检索消息的队列配置为FIFO。我们使用Spring来配置检索功能,容器(org.springframework.jms.listener.DefaultMessageListenerContainer)和消息侦听器(org.springframework.jms.core.support.JmsGatewaySupport)都是单例。此外,该容器已默认将WorkManager配置为任务执行器。为了保证消息按照预期的

我们的应用程序运行在WebLogic 12c中,正在从队列系统中检索消息,我们从中检索消息的队列配置为FIFO。我们使用Spring来配置检索功能,容器(org.springframework.jms.listener.DefaultMessageListenerContainer)和消息侦听器(org.springframework.jms.core.support.JmsGatewaySupport)都是单例。此外,该容器已默认将WorkManager配置为任务执行器。为了保证消息按照预期的顺序(即消息发送到队列的顺序)进行处理,我们在侦听器中使用了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 锁已被线程获取:28 退出计数:1 收到来自XXX的消息1/1收到消息ID1。 线程已获取锁:54 退出计数:1 从XXX收到消息1/1,收到消息ID2。 *****错误***** 锁将由线程释放:54 锁将由线程释放:28 我们为什么会有这种行为?有什么想法吗

非常感谢您的advanced。

更改

logger.warn("Lock has been acquired by thread: " + Thread.currentThread().getId());

您可能会看到,
System.identityHashCode
将是两个不同的数字。如果是同一个对象,则identityHashCode将是相同的。如果它们不同,那就意味着它们是不同的对象


这说明存在多个
ReentrantLock
实例,并且不支持对不同实例的互斥。

考虑到
ReentrantLock
不起作用的可能性接近于零,我建议您将
输出到日志,为了确保您的类是一个单例。还要检查您是否没有对从此锁创建的某些条件调用
await()
。如果您想绝对确定,可以将锁设置为静态,但从设计角度看,这将是一个灾难,您应该使用logger.debug()而不是logger.warn()。如果您选择warn()是因为debug()消息没有显示在您的日志中,那么学习如何配置log4j是值得的:谢谢大家。user3707125:我将检查侦听器是否为单例,并且应用程序中只有一个实例处于活动状态。talex:不,wait()不会在任何地方调用。斯金尼:这是我最后的资源。詹姆斯:事实上,这个日志是一个定制的日志,出于隐私的原因,我已经在帖子中展示了它。也许这引起了混乱。无论如何,谢谢你的链接。非常感谢你,约翰。我将执行你的建议。一旦我得到结果,我会在这里分享。
logger.warn("Lock has been acquired by thread: " + Thread.currentThread().getId() + " And Object " + System.identityHashCode(this));