Programa Java para demostrar la inicialización diferida no segura para subprocesos

En los últimos años, la programación orientada a objetos ha formado los pilares/bases del desarrollo de sitios web y aplicaciones (software). Java y Python son lenguajes de programación orientados a objetos populares, de los cuales Oracle ofrece y mantiene el primero, mientras que el último es de código abierto. Java junto con marcos robustos y fáciles de configurar como los marcos Springhace que la parte de integración y configuración del desarrollo de software sea muy fácil y optimizada. Uno de los cuatro pilares fundamentales de la orientación a objetos de Java se conoce como encapsulación, lo que significa vincular instancias, variables y métodos, a menudo denominados indistintamente funciones, en una clase. El proceso de usar esas variables de instancia y métodos usando una nueva palabra clave para crear un objeto de clase se llama creación de instancias en Java. Tenemos dos formas de crear instancias de objetos en Java, que son Eager y Lazy y ambas tienen sus aplicaciones prácticas en el mundo real.

La creación de instancias perezosas también se conoce como creación de instancias bajo demanda.en el que el objeto de la clase solo se instancia cuando se requiere (es decir, es dinámico). Esto nos ayuda a ahorrar potencia de procesamiento computacional y memoria cuando hablamos de grandes programas de software. Thread es como una pequeña función/proceso computacional simple de un programa que se puede ejecutar simultáneamente en forma paralela para mejorar la velocidad de procesamiento. Como día a día, avanzamos hacia potentes sistemas de procesamiento multinúcleo con subprocesos múltiples de alta GPU/velocidad de reloj que han descubierto una amplia gama de aplicaciones en la programación. Un entorno/código seguro para subprocesos es un código que, incluso si se ejecuta más de una vez (muchas veces), también produce la salida lógica de negocios deseada y no muestra un comportamiento anómalo. 

Acercarse:

Con la ayuda de un estudio de caso simple de reserva de mesa de restaurante , intentaremos comprender cómo funciona la creación de instancias perezosas y qué le sucede a un código seguro sin subprocesos en un entorno de subprocesos múltiples. El siguiente es el enfoque de nuestro caso de estudio Restaurant Table Booking,

  1. Hay una clase Restaurant en el programa que tiene el método main() y actúa como un restaurante cuya mesa se puede reservar en línea.
  2. La mesa 1 , que se ilustra como clase Singleton , es una de las mesas de este restaurante que se puede reservar en línea.
  3. Se crean varios subprocesos en el programa que se ilustran como clientes que intentan reservar/reservar la mesa 1 a través de la instanciación diferida de la clase Mesa 1.
  4. Hay una verificación simple para ver si la mesa 1 ya está reservada / reservada para otro cliente, si es así, se muestra un mensaje de disculpa a la solicitud del cliente actual junto con la mesa 1 para la que ya está reservada, de lo contrario, la mesa 1 está reservada para el nombre del cliente actual .
  5. Luego, tenemos la capacidad de ejecutar dos subprocesos al mismo tiempo, demostramos cómo se produce un comportamiento anómalo porque el código no es seguro para subprocesos, lo que ilustra que si dos clientes intentan reservar/reservar table1 al mismo tiempo, ambos podrían obtener un mensaje de éxito de la reserva, pero desafortunadamente la mesa 1 estaría reservada/reservada solo para 1 de ellos.
  6. Por último, presentamos Thread.sleep() para tener un retraso en el inicio del tercer hilo (cliente) que recibe el mensaje correcto de que la mesa ya está reservada/reservada, lo que indica que Lazy Instatiation funciona perfectamente bien, pero el código no es hilo. -seguro en el entorno de subprocesos múltiples.

Implementación: Reserva de mesa en restaurante

El siguiente estudio de caso de reserva de mesa de restaurante nos ayudará a comprender la creación de instancias perezosas que no son seguras para subprocesos. En este estudio de caso, tenemos un restaurante que tiene una mesa llamada Table1 que está disponible para reservas/reservas en línea. Se realizan varios Threads que se ilustran como clientes que intentan reservar o reservar una mesa1. En la práctica, si la mesa 1 no está reservada, debe reservarse para la primera solicitud del cliente y mostrarse en consecuencia. Si ya está reservado, debería mostrar que lo sentimos, ya está reservado para otros clientes (especifique su nombre). Veremos cómo si dos subprocesos (clientes) intentan reservar la mesa simultáneamente al mismo tiempo, se produce un error.

Ejemplo

Java

// Java Program to Demonstrate the Lazy initialization
// non-thread-safe
 
// Importing input output classes
import java.io.*;
 
// Class 1
// Helper class behaving as a Singleton Class
class Table1 {
 
    // Lazy Instantiation also referred as On-demand
    // Instantiation
 
    // Private static member variables
    private static Table1 table1;
    private static String customerNameBooked;
 
    // Constructor of this class which is private
    // To display customer name whom table1 is booked for
    private Table1(String customerName)
    {
 
        // Print and display the customer name
        System.out.println("Table1 is now Booked for "
                           + customerName);
 
        // Booking under the same person
        customerNameBooked = customerName;
    }
 
    // Non thread-safe block of code to
    // demonstrate thread safe with updation in its methods
 
    // Method 1
    // To get the status of table
    public static Table1
    getTable1Instance(String customerName)
    {
 
        // If table is nor book/reserve
        if (table1 == null) {
 
            // book under the derired customer name
            table1 = new Table1(customerName);
        }
 
        // If table is already booked
        else
 
            // Calling th method
            tableBooked(customerName);
 
        return table1;
    }
 
    // Method 2 (auxiliary)
    // To display whom table is booked for
    private static void tableBooked(String customerName)
    {
 
        // Print the custom name and
        // name of customer under which table i booked
        System.out.println(
            "Sorry " + customerName
            + " Table 1 is already Booked for "
            + customerNameBooked);
    }
}
 
// Class 2
// Main class
public class Restaurant {
 
    // Main driver method
    public static void main(String args[])
    {
 
        // Now we will be creating various threads as
        // customer who wish to book Table1 in Restaurant
 
        // Creating first customer(Thread-0)
        // using Runnable interface
        Thread t1 = new Thread(new Runnable() {
            // run() method for the thread
            public void run()
            {
 
                // Getting the table status
                Table1 customer1
                    = Table1.getTable1Instance("ABC");
            }
        });
 
        // Similarly repeating same for other customers
 
        // Again creating second customer(Thread-1)
        // using Runnable interface
        Thread t2 = new Thread(new Runnable() {
            // run() method for this thread
            public void run()
            {
 
                Table1 customer2
                    = Table1.getTable1Instance("XYZ");
            }
        });
 
        // Creating third customer(Thread-2)
        // using Runnable interface
        Thread t3 = new Thread(new Runnable() {
            // run() method for this thread
            public void run()
            {
 
                Table1 customer3
                    = Table1.getTable1Instance("PQR");
            }
        });
 
        // Now starting the threads
        // using start() method
        t1.start();
        t2.start();
 
        // Try block to check for exceptions if any
        try {
 
            // Intentionally having a Thread.sleep(1000) to
            // demonstrate not Thread-safe environment
            Thread.sleep(1000);
        }
 
        // Catch block to handle the exceptions
        catch (InterruptedException e) {
        }
 
        // Now starting the last thread via same means
        t3.start();
    }
}

Producción:

Figura 1: Demostración de creación de instancias diferidas en un entorno no seguro para subprocesos.

Explicación de salida: se muestra la ejecución del código de secuencia de comandos anterior para la cual reuniremos todos los aspectos para saber cómo no es seguro para subprocesos.   

  • Inicialmente, tenemos 3 subprocesos, a saber , t1, t2 y t3 , que se ilustran como clientes con nombres ABC, XYZ y PQR , respectivamente, que intentan reservar/reservar Table1 en la clase Restaurant .
  • t1 y t2 se inician simultáneamente en el subproceso para demostrar el entorno de subprocesos múltiples. Ambas llamadas al método getTable1Instance() para reservar la mesa, aquí la clase Table1 se comporta como una clase singleton de Java cuya instancia solo debe crearse una vez, lo que ilustra que table1 puede estar ocupada por solo 1 cliente a la vez.
  • Pero como el código no es seguro para subprocesos, la tabla está reservada para ambos clientes (es decir, ABC y XYZ ), como podemos ver, la instancia de table1 se crea dos veces a pesar de estar marcada para tener la propiedad de Lazy Instanciation of Singleton clase.
  • Luego introducimos un retraso en el inicio de la ejecución del subproceso t3 (con el nombre del cliente como PQR ) al tener Thread.sleep() , por lo que podemos ver ahora que el mensaje que se muestra en PQR es correcto de acuerdo con la lógica comercial que una vez que la tabla fue reservado, solo debe mostrar el mensaje de disculpa al cliente actual y mostrar para qué cliente está reservada la mesa. Esto demuestra que Lazy Instanciation funciona bien en la ejecución en serie de subprocesos que no son códigos seguros para subprocesos.
  • Si hay subprocesos múltiples que funcionan en paralelo, el código muestra un comportamiento anómalo al reservar la misma instancia de la mesa para dos clientes que intentan reservar al mismo tiempo, pero finalmente termina una reserva solo para uno cuyo nombre es entonces se muestra para el subproceso t3 ( PQR ) que se ve en la figura 1 a continuación, que es una captura de pantalla de salida de muestra.

Conclusión: por lo tanto, con la ayuda de un estudio de caso simple de reserva de mesa de restaurante, el concepto de creación de instancias perezosas en un entorno/código no seguro para subprocesos se explica anteriormente .

Publicación traducida automáticamente

Artículo escrito por shreyasangchekar 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 *