clase Singleton no está sincronizado y volviendo varias instancias

techi:

Hay algo malo con mi código de abajo. Me estoy haciendo varias instancias de la misma clase singleton al llamar desde múltiples hilos de un mismo proceso. Estoy esperando que el programa debe imprimir "Creación de instancia" solamente una vez, pero es la impresión 3 veces (es decir, por cada hilo).

package SingleTon;

class SingleTon implements Runnable {
    String name;
    int salary;
    private static SingleTon singleTonInstance;

    SingleTon() {

    }

    public static SingleTon getInstance() {
        if (singleTonInstance == null) {
            synchronized (SingleTon.class) {
                System.out.println("Creating instance");
                singleTonInstance = new SingleTon();
            }
        }
        return singleTonInstance;
    }

    @Override
    public void run() {
        System.out.format("Thread %s is starting\n",Thread.currentThread().getName());
        getInstance();
    }

}

package SingleTon;

public class SingleTonDemo {

    public static void main(String[] args) {
        System.out.println("test");
        SingleTon t = new SingleTon();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        t1.start();
        t2.start();
        t3.start();
    }

}

Salida:

test
Thread Thread-0 is starting
Thread Thread-2 is starting
Thread Thread-1 is starting
Creating instance
Creating instance
Creating instance
EJK:

Es necesario cambiar la siguiente:

1) Haga su constructor por defecto privado. Como está escrito, es el paquete-privada y puede ser llamado por otras clases en el mismo paquete.

private SingleTon() {
}

Una vez hecho esto, su SingleTonDemoclase ya no será capaz de llamar al constructor y se verá obligado a utilizar el getInstance()método. Actualmente, cada llamada al constructor es la creación de una nueva instancia.

2) Sincronizar todo el getInstance()método. Como está escrito, 2 hilos separados pueden obtener un valor nulo para singleTonInstance, y de este modo cada hilo crearían una nueva instancia.

    public static SingleTon getInstance() {

2a) Un enfoque alternativo a garantizar que sólo hay una instancia de la clase es utilizar inicialización estática. En la declaración de la variable estática, se crea el objeto:

private static SingleTon singleTonInstance = new SingleTon();

La JVM se asegurará de que esto se llama una sola. Que también mejora su método getInstance como se puede cambiar a:

public static SingleTon getInstance() {
    return singleTonInstance;
}

La ventaja de este enfoque es que no sólo es el método getInstance más simple, sino que también no incurrir en los gastos generales de ser sincronizado.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=225495&siteId=1
Recomendado
Clasificación