Prefacio
Recientemente, encontré un problema de punto muerto al comenzar el proyecto de primavera. Al usar Jstack para obtener la pila de subprocesos, puede ver que dos hilos tienen punto muerto:
Proceso de solución:
El código fuente de DefaultSingletonBeanRegistry.getSingleton() es el siguiente. Puede ver que este método requiere que se bloqueen los SingletOnObjects.
El código fuente del segundo xxx.subject.core.cache.datalocalcacheinit.afterpropertiesset es el siguiente:
Puede ver que cuando se inicialice este bean, iniciará el hilo y llamará initData() de otro bean para cargar datos de la base de datos. La inicialización del frijol dataLocalCacheinit se considerará completa después de cargar los datos.
De la pila anterior, podemos ver que cuando el contenedor de resorte inicializa el frijol, bloqueará el objeto SingletOnObjects; Abrimos un hilo en afterPropertiesSet() , que eventualmente activará el resorte para cargar otro frijol. El primer hilo (el hilo principal que inicializa Spring) no ha liberado el bloqueo, y el segundo hilo (el hilo que se abre solo) también debe obtener el bloqueo de objeto SingletOnObjects, que causa un punto muerto. El fenómeno que se muestra es que el contenedor de resorte está atascado allí y no puede completar la inicialización de todos los frijoles.
Echemos un vistazo a un ejemplo, que es muy similar al código real en nuestro proyecto. FirstBean llama al método en configelper:
Public Class FirstBean implementa InitializingBean {@Override public void AfterPropertIesset () lanza la excepción {System.out.println ("El primer bean está inicializando ..."); Bloquingqueue Queue = New ArrayBlockingqueue (10); Thread Thread = new Thread () {@Override public void run () {confighelper.dosomthing (); cola.add (1); }}; Thread.Start (); queue.take (); System.out.println ("Primero obtener datos ..."); }} El código Confighelper es el siguiente: obtenga otro frijol a través de BeanFactory
Public Class Confighelper implementa BeanFactoryaware {Factory privado estático de BeanFactory; @Override public void setBeanFactory (BeanFactory BeanFactory) lanza Beansexception {this.Factory = BeanFactory; } public static void dosomething () {SecondBean Bean = (Secondbean) Factory.getBean ("segundo"); frijoles.say (); }} El código de Secondbean es simple de la siguiente manera:
clase pública Secondbean {public void say () {System.out.println ("Secondbean ..."); }}El archivo de configuración de Spring y el código de inicio son los siguientes. Puedes encontrar muertos de punto al correr:
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" "" "" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beanss.xsd"> <bean id = "config"> </bean> <bean id = "primero" </bean> </beans> public class Main {public static void main (string [] args) {applicationContext context = new FilesystemXMLAplaPlicationContext ("Src/Main/Java/Net/Aty/Spring/Deadlock/Deadlock.xml"); // Cargue el archivo de configuración de Spring}}Cuando se inicializa la primavera, si iniciamos el hilo para adquirir el bean en algunos puntos de extensión proporcionados por la primavera (beanFactoryaware/inicializingbean, etc.), el contenedor estará bloqueado. Debido a que Spring inicializa los frijoles singleton (la mayoría de los frijoles son singletons) agregarán cerraduras. Si la cerradura no se ha lanzado cuando se inicializa 1 frijol, y otro hilo desencadena nuevamente el frijol cargando el resorte, aparecerá un punto muerto.
Resolver el problema anterior es simple: FirstBean lógicamente depende de ConfightElper y Secondbean, pero no mostramos la relación lógica de la primavera. Cuando la primavera se inicializa FirstBean, ingrese afterPropertiesSet() . Este método activará la carga de los otros 2 frijoles cuando se enciende el hilo. Solo necesitamos mostrar la dependencia de la primavera y dejar que Spring se cargue primero y Secondbean.
<bean id = "config" depends-on = "segundo"> </bean> <bean id = "primero" depends-on = "config"> </ bean> <bean id = "segundo"> </rano>
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.