Programa Java para demostrar la inicialización anidada para la clase Singleton

Una clase Singleton es capaz de producir una sola instancia. Cada clase Singleton tiene un método getInstance que devuelve su objeto. Cuando se llama al método getInstance por primera vez, se genera, almacena y luego se devuelve un objeto de la clase. En llamadas posteriores a getInstance, se devuelve el mismo objeto generado anteriormente.

La inicialización anidada se puede utilizar para crear clases Singleton.
En la implementación a continuación, estamos creando una clase Singleton utilizando la inicialización anidada. Haga las siguientes observaciones:

  • El constructor predeterminado sin argumentos de esta clase se hace privado para evitar que otras clases accedan directamente a él y creen objetos de Singleton.
  • La clase Singleton tiene un método getInstance público estático con Singleton como tipo de retorno. Esto será utilizado por otras clases para obtener el objeto de Singleton.
  • Hay una clase anidada dentro de la clase Singleton. Esta clase anidada tiene una variable de instancia que almacena el objeto de la clase Singleton.
  • El método getInstance toma valor de esta variable de instancia y lo devuelve al sitio de la llamada.

Demostración de la creación de una clase Singleton utilizando la inicialización anidada

Java

// Java Program to demonstrate Singleton Class
// using Nested Initialization
  
class Singleton {
  
    // a member variable
    String str = "GFG!";
  
    // Nested class has just 1 role i.e.creation of the
    // Singleton object and storing it in Instance variable
    private static class Nested {
        static Singleton Instance = new Singleton();
    }
  
    // The getInstance() method returns the object of
    // Singleton class stored in Instance variable
    public static Singleton getInstance()
    {
        return Nested.Instance;
    }
  
    // no-argument constructor has to be made private
    // this forces other classes to use getInstance() method
    // in order to obtain the instance of Singleton class
  
    private Singleton()
    {
        System.out.println("Object made");
    }
}
  
public class Main {
  
    public static void main(String[] args)
    {
        Singleton obj1 = Singleton.getInstance();
        Singleton obj2 = Singleton.getInstance();
  
        // make changes to obj1.str and output obj2.str
        obj1.str = "geeksforgeeks!";
  
        System.out.println(obj2.str);
    }
}
Producción

Object made
geeksforgeeks!

Ventajas de la inicialización anidada:

  • Carga lenta
  • Seguridad de subprocesos

Carga perezosa :

  1. La carga diferida es simplemente posponer la creación del objeto hasta que realmente se necesite.
  2. Da como resultado un mayor rendimiento ya que se reduce la sobrecarga durante el inicio del programa.
  3. En nuestro caso, el objeto de la clase Singleton no se crea hasta que se llama por primera vez al método getInstance.

Seguridad de subprocesos: la seguridad de subprocesos es esencial; de lo contrario, los programas de subprocesos múltiples pueden producir resultados aleatorios inesperados.

  • Una implementación no segura para subprocesos de la clase Singleton 

Java

// Java Program to demonstrate need of Thread-Safety
  
class Singleton1 {
    static Singleton1 obj;
  
    private Singleton1()
    {
        System.out.println("Object made");
    }
  
    // This method returns obj
    // If both the threads enter getInstance simultaneously
    // then both see obj as null, hence 2 objects of
    // Singleton1 are created this defeats purpose of
    // Singleton class
    static Singleton1 getInstance()
    {
        if (obj == null)
            obj = new Singleton1();
  
        return obj;
    }
}
  
public class Main {
    public static void main(String[] args)
    {
  
        // Thread 1 will call getInstance
        Thread t1 = new Thread(new Runnable() {
            public void run()
            {
                Singleton1 a = Singleton1.getInstance();
            }
        });
  
        // Thread 2 will also call getInstance
        Thread t2 = new Thread(new Runnable() {
            public void run()
            {
                Singleton1 b = Singleton1.getInstance();
            }
        });
  
        // Start both the Threads
        t1.start();
        t2.start();
    }
}
Producción

Object made
Object made
  • La inicialización anidada es segura para subprocesos , esto se debe a que, a diferencia de la implementación anterior en la inicialización anidada, el método getInstance no crea un objeto, simplemente lo devuelve. El objeto se crea cuando se inicializa la clase anidada y esto sucede solo una vez cuando se llama al método getInstance por primera vez.

Implementación segura para subprocesos de la clase Singleton

Java

// Java Program to demonstrate Thread-Safety
// in NestedInitialization
  
class Singleton {
  
    private static class Nested {
        static Singleton Instance = new Singleton();
    }
  
    // This method returns Object, does not create it
    // Object is created on initialization of Nested class
    // which happens only once.
    public static Singleton getInstance()
    {
        return Nested.Instance;
    }
  
    private Singleton()
    {
        System.out.println("Object made");
    }
}
  
public class SingletonDemo {
    public static void main(String[] args)
    {
  
        // Thread 1 will call getInstance
        Thread t1 = new Thread(new Runnable() {
            public void run()
            {
                Singleton a = Singleton.getInstance();
            }
        });
  
        // Thread 2 will also call getInstance
        Thread t2 = new Thread(new Runnable() {
            public void run()
            {
                Singleton b = Singleton.getInstance();
            }
        });
  
        // Start both the Threads
        t1.start();
        t2.start();
    }
}
Producción

Object made

Nota: En la implementación anterior, hemos logrado la seguridad de subprocesos sin usar la palabra clave sincronizada. Este es un punto a favor ya que se sabe que la palabra clave sincronizada afecta notablemente el rendimiento.

Publicación traducida automáticamente

Artículo escrito por sanatr y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *