usar patrones patron mvc example diseño conexion como java synchronization singleton

patrones - Java se sincroniza en patrón singleton



patrones de diseño java (4)

¿Es necesario aplicar la palabra clave synchronize a cada método de una clase que implemente el patrón singleton de esta manera?

public class Singleton { private Singleton(){} public synchronized static Singleton getInstance() { if(instance == null) instance = new Singleton (); return instance; } public void DoA(){ } }

Como Singletons no expone un constructor público y el método getInstance () está sincronizado, no es necesario sincronizar el método DoA y cualquier otro método público expuesto por la clase Singleton.

¿Es este razonamiento correcto?


Es como cualquier otra clase. Puede o no necesitar más sincronización.

Considere el siguiente ejemplo:

public class Singleton { private Singleton() {} public synchronized static Singleton getInstance() { ... } private int counter = 0; public void addToCounter(int val) { counter += val; } }

Si la clase se va a utilizar desde múltiples hilos, addToCounter() tiene una condición de carrera. Una forma de solucionarlo es haciendo que addToCounter() sincronizado:

public synchronized void addToCounter(int val) { count += val; }

Hay otras formas de corregir la condición de carrera, por ejemplo, usando AtomicInteger :

private final AtomicInteger counter = new AtomicInteger(0); public void addToCounter(int val) { counter.addAndGet(val); }

Aquí, hemos corregido la condición de carrera sin usar synchronized .


Bueno, el objetivo de la clase Singleton es que haya como máximo una instancia de ella y que todos los Threads puedan acceder a ese mismo objeto.

Si no sincroniza el método getInstance , podría suceder lo siguiente

Thread1 ingresa getInstance()

Thread2 ingresa getInstance()

Thread1 evalúa la instance == null en true

Thread2 evalúa la instance == null en true

Thread1 asigna instance y devuelve

Thread2 reasigna instance = new Singleton() y regresa.

Ahora los hilos tienen una instancia diferente de la clase Singleton, que es lo que debería haberse evitado con este patrón.

La sincronización impide que ambos subprocesos puedan acceder al mismo bloque de código al mismo tiempo. Por lo tanto, se necesita sincronización en un entorno multiproceso cuando crea instancias de clases singleton.

Ahora suponiendo que múltiples hilos intentarán acceder a los métodos de Singletons al mismo tiempo, la sincronización también podría ser necesaria en esos métodos. Especialmente si cambian los datos en lugar de solo leerlo, esto es cierto.


La forma correcta (mejor en realidad) de usar Singleton

private static singleton getInstance() { if (minstance == null) { synchronized (singleton.class) { if (minstance == null) { minstance = new singleton(); } } } return minstance; }


Inicialización lenta y solución segura de subprocesos:

public class Singleton { public static class SingletonHolder { public static final Singleton HOLDER_INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.HOLDER_INSTANCE; } }