머리말
최근에, 나는 봄 프로젝트를 시작할 때 교착 상태 문제를 겪었습니다. Jstack을 사용하여 스레드 스택을 얻을 때 두 개의 스레드에 교착 상태가 있음을 알 수 있습니다.
솔루션 프로세스 :
기본값 소스 소스 DefaultSingletonBeanRegistry.getSingleton() 소집. 이 방법은 싱글토 노브 젝트를 잠겨 필요하다는 것을 알 수 있습니다.
두 번째 xxx.subject.core.cache.datalocalcacheinit의 소스 코드는 다음과 같습니다.
이 Bean이 초기화되면 스레드를 시작하고 데이터베이스에서 데이터를로드하기 위해 다른 Bean의 initData() 메소드를 호출합니다. 데이터가로드 된 후 Datalocalcacheinit Bean의 초기화는 완료된 것으로 간주됩니다.
위의 스택에서 스프링 컨테이너가 콩을 초기화 할 때 SingletonObjects 객체를 잠그는 것을 알 수 있습니다. afterPropertiesSet() 메소드에서 스레드를 열고 결국 다른 Bean을로드하도록 스프링을 트리거합니다. 첫 번째 스레드 (스프링을 초기화하는 메인 스레드)는 잠금을 해제하지 않았으며, 두 번째 스레드 (자체로 열린 스레드)는 또한 단일 토 노브 젝트 객체 잠금 장치를 얻어야하므로 교착 상태가 발생합니다. 표시된 현상은 스프링 컨테이너가 거기에 붙어 있고 모든 콩의 초기화를 완료 할 수 없다는 것입니다.
프로젝트의 실제 코드와 매우 유사한 예를 살펴 보겠습니다. FirstBean은 Confighelper에서 메소드를 호출합니다.
공개 클래스 FirstBean은 초기화를 구현합니다. Blockingqueue 대기열 = 새로운 Arrayblockingqueue (10); 스레드 스레드 = 새 스레드 () {@override public void run () {confighelper.dosomething (); queue.add (1); }}; thread.start (); queue.take (); System.out.println ( "먼저 데이터 가져 오기 ...."); }} Confighelper 코드는 다음과 같습니다. Beanfactory를 통해 다른 Bean을 얻으십시오.
공공 계급 Confighelper는 Beanfactoryaware {Private Static Beanfactory Factory; @override public void setbeanfactory (beanfactory beanfactory)는 beansexception을 던졌습니다. {this.factory = beanfactory; } public static void dosomething () {SecondBean Bean = (SecondBean) factory.getBean ( "Second"); bean.say (); }} SecondBean 코드는 다음과 같이 간단합니다.
공개 클래스 SecondBean {public void say () {System.out.println ( "SecondBean ..."); }}스프링 구성 파일 및 시작 코드는 다음과 같습니다. 실행할 때 교착 상태를 찾을 수 있습니다.
<? xml 버전 = "1.0"alcoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : xsi = "http://ww.w.w3.org/2001/xmlschema-instance" xsi : schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id = "config"> </beans> public class main {public static void main (string [] args) {ApplicationContext Context = new FilesyStemxMlApplicationContext ( "SRC/MAIN/JAVA/NET/ATY/SPRING/DEADLOCK/DEADLOCK.XML"); // SPRING CONFIGURATION 파일}}}}}}}}}}}}.스프링이 초기화되면 스프링 (BeanFactoryAware/초기화 비안 등)이 제공 한 일부 확장 지점에서 콩을 얻기 위해 스레드를 시작하면 컨테이너가 교착 상태가됩니다. 스프링은 싱글 톤 콩을 초기화하기 때문에 (대부분의 콩은 싱턴입니다) 자물쇠를 추가합니다. 1 개의 Bean이 초기화 될 때 자물쇠가 해제되지 않고 다른 실이 스프링 로딩 Bean을 다시 트리거하면 교착 상태가 나타납니다.
위의 문제를 해결하는 것은 간단합니다. FirstBean은 논리적으로 Confighelper와 Secondbean에 의존하지만 Spring의 논리적 관계는 표시되지 않습니다. Spring이 FirstBean을 초기화하면 afterPropertiesSet() 입력하십시오. 이 방법은 스레드가 켜져있을 때 다른 2 개의 콩의 하중을 트리거합니다. 우리는 단지 스프링의 의존성을 보여주고 스프링 하중 Confighelper와 Secondbean을 먼저 두어야합니다.
<bean id = "config"는 종속적 인 경우 = "second"> </bean> <bean id = "first"feencs-on = "config"> </bean> <bean id = "secon"> </bean>
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.