En los programas de Java, a veces puede ser necesario posponer algunas operaciones de inicialización de objetos de alto nivel y solo se inicializan al usar estos objetos. Esto se llama inicialización retrasada o carga perezosa
Mire una inicialización de retraso inseguro:
Después de que el hilo A se ejecuta 1, encuentra que la instancia del objeto es nula y está lista para nueva, mientras que el hilo B es nuevo primero, lo que causa un error.
Podemos usar bloqueos de sincronización para garantizar la corrección:
Pero sincronizar todo el método es demasiado costoso, y a la gente se le ocurrió el bloqueo de doble verificación:
El bloqueo de sincronización utilizado en el rango mínimo parece alcanzar el propósito utilizando la doble verificación, pero esto tiene un problema: cuando un hilo de ejecutar 4, el hilo B 7 aún no se ha ejecutado, y el hilo dura una instancia! = NULL. El hilo B 7 aún no se ha ejecutado, entonces, ¿por qué sucede esto?
Eche un vistazo a la implementación clave subyacente de la nueva instancia ()::
De hecho, primero debe realizar 1 asignar memoria, luego inicializar el objeto y establecer la instancia. Luego hay un reorden aquí, y el orden de 2 y 3 puede ser reemplazado:
Entonces, cuando B todavía ejecuta 7, A determina en 4 que el objeto de instancia se ha inicializado. Si se llama a la instancia antes, CTORInstance (memoria) causará un error.
Hay dos soluciones:
1. Declarar el objeto de instancia como volátil, prohibirá el reordenamiento de 2 y 3
2. Utilizando una solución basada en la inicialización de la clase: el JVM realizará la inicialización de la clase en la etapa de inicialización de la clase (es decir, después de que la clase se carga y antes de que el hilo lo use). existir
Durante la inicialización de la clase de ejecución, el JVM adquirirá un bloqueo. Este bloqueo puede sincronizar la inicialización de la misma clase por múltiples hilos
Encontraremos que el código de implementación del esquema basado en la inicialización de la clase es más simple. Pero el esquema de bloqueo de doble verificación basado en volátiles tiene una ventaja adicional: además de retrasar la inicialización de los campos estáticos, también puede retrasar la inicialización de los campos de instancias. La inicialización del retraso de campo reduce la sobrecarga de las clases de inicialización o la creación de instancias, pero aumenta la sobrecarga de los campos de acceso que se retrasan inicializados. La mayoría de las veces, la inicialización normal es mejor que la inicialización retrasada. Si realmente necesita usar la inicialización tardía segura de hilos, por ejemplo, los campos, utilice el esquema de inicialización de retraso basado en volátiles descrito anteriormente; Si realmente necesita usar la inicialización tardía segura de hilos para campos estáticos, utilice el esquema de inicialización basado en la clase descrito anteriormente.
Resumir
Lo anterior es el código de implementación del bloqueo de doble verificación Java introducido por el editor. Espero que sea útil para todos. Si tiene alguna pregunta, déjame un mensaje y el editor responderá a todos a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!