发现一处dboss 初始化死锁问题,我的代码,由于initServiceContext()是另外一个thread来执行的,和spring本身的初始化线程产生死锁。
public class ServiceManager implements InitializingBean, BeanFactoryAware { private List<Object> providers; private BeanFactory beanFactory; public void setProviders(List<Object> providers) { this.providers = providers; } @Override public void afterPropertiesSet() throws Exception { Thread thread = new Thread(new Runnable() { @Override public void run() { ServiceContext serviceContext = initServiceContext(); ServiceRemoting serviceRemoting = new NioServiceRemoting(); serviceRemoting.init(serviceContext); serviceRemoting.start(8989); } }); thread.setName("Dboss-Service-Manager-Thread"); thread.setDaemon(true); thread.start(); } protected ServiceContext initServiceContext() { DataResolverFactory dataResolverFactory = new DataResolverFactoryImpl(); ServiceRegister serviceRegister = new ServiceRegister(); for (Object provider : providers) { String beanName = provider.toString(); serviceRegister.registe(beanName, this.beanFactory.getBean(beanName)); } return new ServiceContextImpl(serviceRegister, dataResolverFactory); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } }
解决办法: 把initServiceContext放在线程外面来做。
死锁原因分析,通过jstack能自动检测死锁,关键节点已经关注,简单的解释一下就是:
thread1: 获取lockA 等待lockB
AbstractBeanFactory.getBean()-->DefaultSingletonBeanRegistry.getSingleton()-->DefaultListableBeanFactory.getBeanDefinitionNames()
main: 获取lockB 等待lockA
ContextLoaderListener.contextInitialized()-->DefaultListableBeanFactory.preInstantiateSingletons()---->DefaultSingletonBeanRegistry.getSingleton()
"Dboss-Service-Manager-Thread" daemon prio=10 tid=0x00000000581ad800 nid=0x3683 waiting for monitor entry [0x0000000041a10000] java.lang.Thread.State: BLOCKED (on object monitor) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinitionNames(DefaultListableBeanFactory.java:297) - waiting to lock <0x00000000ef560190> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:329) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:320) at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:187) at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:861) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) - locked <0x00000000ef5605b0> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) - locked <0x00000000ef5605b0> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
扫描二维码关注公众号,回复:
1292713 查看本文章