java - 在 DefaultSingletonBeanRegistry 和 CachingConnectionFactory 中创建 bean 时发生死锁

标签 java spring deadlock spring-amqp spring-bean

我的应用程序在 bean 初始化时发现死锁。两个 Bean 在不同的线程中等待并保存彼此所需的资源。在bean初始化期间,“BeanA”类通过调用方法[CachingConnectionFactory >> createConnection()]并等待ConcurrentHashMap 的锁定来锁定“connectionMonitor”对象DefaultSingletonBeanRegistry 中的“singletonObjects”。而“BeanB”已通过调用方法[DefaultSingletonBeanRegistry >> getSingleton()]锁定了ConcurrentHashMap“singletonObjects”,并正在等待CachingConnectionFactory中“connectionMonitor”对象的锁定。

线程转储:-

主题 1:-

   java.lang.Thread.State: BLOCKED (on object monitor)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:187)
- waiting to lock <0x000008001202c048> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:399)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:431)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:515)
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1197)
at org.springframework.amqp.rabbit.core.RabbitAdmin.initialize(RabbitAdmin.java:457)
at org.springframework.amqp.rabbit.core.RabbitAdmin$11.onCreate(RabbitAdmin.java:419)
at org.springframework.amqp.rabbit.connection.CompositeConnectionListener.onCreate(CompositeConnectionListener.java:33)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:553)
- locked <0x000009fff2a3a620> (a java.lang.Object)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:90)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:76)
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:496)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1331)
at java.lang.Thread.run(Thread.java:748)

线程 2:-

   java.lang.Thread.State: BLOCKED (on object monitor)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:544)
- waiting to lock <0x000009fff2a3a620> (a java.lang.Object)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1431)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1412)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1388)
at org.springframework.amqp.rabbit.core.RabbitAdmin.declareQueue(RabbitAdmin.java:207)
<some call stack lines removed from here for privacy>
- locked <0x000008001202c048> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)

我正在尝试在 @PostConstruct 方法中建立与兔子的连接,如下所示:-

BeanA {
    
    @PostConstruct
    public void init() {
      <call to CachingConnectionFactory.createConnection is made using some code)>
    }
}

BeanB {
    
    @PostConstruct
    public void init() {
      <call to CachingConnectionFactory.createConnection is made using some code)>
    }
}

请建议需要做什么。谢谢

最佳答案

从初始化阶段开始访问连接等低级资源还为时过早。

考虑实现一个 SmartLifecycle 并从 start() 实现调用 createConnection() 而不是 @PostConstruct.

关于java - 在 DefaultSingletonBeanRegistry 和 CachingConnectionFactory 中创建 bean 时发生死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63670363/

相关文章:

java - 使用自定义身份验证了解 Spring Security 中的 "Access Denied"

java - 当 @Embedded 字段的所有列均为 NULL(JPA/Hibernate)时 - 如何防止空指针?

Java/JavaFX : Poll a database for single value update,,同时保持 GUI 中的响应能力

java - Spring session ,部署后从 "local class incompatible"恢复

检查 pthread mutex 是否被锁定或解锁(在线程锁定自身之后)

multithreading - 如何解除阻塞等待信号量的所有线程?

java - 在没有任何 C/C++ 或 make 知识的情况下使用 FFmpeg for android

java - Tomcat 数据源 - 最大 Activity 连接数

multithreading - 为什么左/右顺序在哲学家晚餐的指挥解决方案中很重要?

用于excel View 解析器的spring Java配置