thread safe pattern best java multithreading synchronization thread-safety singleton

safe - singleton synchronized java



Enlazar Singletons seguros en Java (1)

Respuesta 1: static synchronized métodos static synchronized usan el objeto de la clase como el bloqueo, es decir, en este caso Singleton.class .

Respuesta 2: El lenguaje Java, entre otras cosas:

  • carga clases cuando se accede / usa por primera vez
  • garantiza que antes de que se permita el acceso a una clase, todos los inicializadores estáticos se han completado

Estos dos hechos significan que la clase estática interna SingletonHolder no se carga hasta que se llama al método getInstance (). En ese momento, y antes de que el hilo que hace que la llamada tenga acceso, la instancia estática de esa clase se crea una instancia como parte de la carga de clases.

¡Esto significa que tenemos una carga lenta y segura, y sin necesidad de sincronización / bloqueos!

Este patrón es el patrón a usar para singletons. Es mejor que otros patrones porque MyClass.getInstance() es el estándar de la industria de facto para singletons: todos los que lo usan saben automáticamente que están tratando con un singleton (con código, siempre es bueno ser obvio), por lo que este patrón tiene la API correcta y la implementación correcta bajo el capó.

Por cierto , vale la pena leer el artículo de Bill Pugh para que esté completo cuando se entienden los patrones de singleton.

El artículo de wikipedia sobre Singletons menciona algunos modos seguros de implementar la estructura en Java. Para mis preguntas, consideremos los Singletons que tienen largos procedimientos de inicialización y muchos hilos a la vez.

En primer lugar, ¿este método no mencionado es seguro para subprocesos y, de ser así, en qué se sincroniza?

public class Singleton { private Singleton instance; private Singleton() { //lots of initialization code } public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } }

En segundo lugar, ¿por qué el siguiente thread de implementación es seguro Y flojo en la inicialización? ¿Qué sucede exactamente si dos hilos entran en el método getInstance() al mismo tiempo?

public class Singleton { private Singleton() { //lots of initialization code } private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

Finalmente, en el segundo ejemplo, ¿qué pasa si un hilo obtiene una instancia primero y otro hilo obtiene una instancia e intenta realizar acciones sobre él antes de que el constructor haya terminado en el primer hilo? ¿Puedes entrar en un estado inseguro entonces?