El patrón de grupo de objetos es un patrón de diseño de creación de software que se usa en situaciones en las que el costo de inicializar una instancia de clase es muy alto. Básicamente, un grupo de objetos es un contenedor que contiene cierta cantidad de objetos. Entonces, cuando se toma un objeto del grupo, no está disponible en el grupo hasta que se devuelve.
Los objetos en el grupo tienen un ciclo de vida:
- Creación
- Validación
- Destruir.
La agrupación de objetos puede proporcionar una gran mejora de la velocidad; funciona mejor cuando el costo de inicializar una instancia de clase es alto, el ritmo de creación de instancias es alto y la cantidad de instancias en uso en un momento dado es baja.
El diseño de Object Pool es útil cuando los objetos son costosos de construir y solo necesitan usarse por un corto período de tiempo. En este patrón de diseño, hacemos un seguimiento de qué objetos instanciados están en uso y cuáles son accesibles.
¿Cómo crear múltiples grupos de objetos?
Todos sabemos cómo crear un solo grupo de objetos. Pero puede haber un requisito para crear múltiples grupos de objetos de tamaño variable. Esto significa que en lugar de crear un solo grupo de objetos de tamaño fijo, podemos tener varios grupos y cada grupo tiene una cantidad diferente de objetos totales.
¿Cuál es el requisito en tiempo real para ello?
La asignación de memoria según sea necesario para el manejo de errores o en escenarios emergentes en la programación se puede lograr generando múltiples grupos de memoria de tamaño variable.
Hay algunos objetos para los que la producción de un nuevo objeto parece ser un poco más costosa, ya que no se consideran livianos. Los objetos de conexión de base de datos, los objetos de analizador, la generación de subprocesos, etc., son ejemplos. Es posible que tengamos que construir numerosos grupos de objetos de este tipo en cualquier aplicación. Debido a que la generación de dichos objetos es costosa, tendrá un impacto negativo en el rendimiento de cualquier programa. Podemos usar el mismo objeto una y otra vez.
Implementación:
aquí estamos creando una clase «Subproceso» cuyos Objetos están allí en grupos y otra clase «Subproceso» que se utiliza para crear múltiples grupos de Objetos «Subproceso».
En nuestra clase Clase de subprocesos (clase 1)
Tenemos miembros de datos:
- «uniqueId» Almacena una identificación única generada para cada objeto de subproceso.
- “nombre” Mantiene el nombre del objeto hilo.
En nuestra clase clase ThreadPool (clase 2)
Tenemos miembros de datos:
- isFirst = verdadero para mantener el valor verdadero inicialmente y cada vez que se crea el primer objeto Subproceso en el grupo, después de la creación del primer objeto, se establece en falso.
- myThreads[] de tipo Thread, que es una referencia de array que se referirá al objeto Thread Class (Thread Pool Array)
- isUsed[] de tipo booleano, que es una array para realizar un seguimiento de los objetos de Thread que están en uso actualmente
- noOfThreadPools para llevar la cuenta del número de grupos de subprocesos y es una propiedad de nivel de clase
- ThreadreferenceCount para llevar la cuenta del número de referencias de subprocesos en un grupo en particular
- poolNum para almacenar un número único dado a cada grupo creado
Ejemplo
Java
// Java Program to Creating Multiple Pools Of Objects of // Variable Size // Importing required classes import java.io.*; import java.util.*; // Class 1 // Helper class class Thread { // Members of this class private int uniqueId; private static int uniqueIDGen = 0; private String thread_name; // Constructor that initializes the objects of Thread // class Thread() { uniqueId = generateUniqueId(); } // Method 1 // To set the value of the data member, // name of the Thread's Object public void setNameOfThread(String name) { thread_name = name; } // Method 2 public String getNameOfThread() { return thread_name; } // Method 3 // To generate a unique id for each Thread's Object private int generateUniqueId() { return uniqueIDGen++; } // Method 4 // To Compare that the "this" reference and // "t1" reference refer to same object public boolean compare(Thread t1) { if (t1.uniqueId == this.uniqueId) { return true; } else { return false; } } } // Class 2 // Helper class class ThreadPool { // member variables of this class // To keep true whenever 1st object of a pool is // created, // after 1st object creation, it is set to false private boolean isFirst = true; // Array reference of myThread (Thread Pool Array) private Thread myThreads[] = null; // Array to Keep track that which Thread's objects // are in use currently private boolean isUsed[] = null; private int n; // To keep count of no of Thread Pools and // is a class level Property private static int noOfThreadPools = 0; // Keeping count of no of thread references // in a particular pool private int ThreadreferenceCount = 0; // To Give a unique number to every Pool Created private int poolNum = 0; // Constructor of class 2 public ThreadPool() { noOfThreadPools++; poolNum = noOfThreadPools; } // Method 1 // To give "size" of each Thread pool and // creating size no of objects of Thread Type, // returning true if successful, else false public boolean initialize(int size) { boolean status = false; if (true == isFirst) { isFirst = false; n = size; // Assign memory of reference of array // using new keyword myThreads = new Thread[n]; for (int i = 0; i < n; i++) { // Creating new object in heap of Thread // Class & myThread[i] reference refer it myThreads[i] = new Thread(); // we are assigning thread name to each // thread String name = Integer.toString(i + 1); name = name.concat( " is the thread number of the pool "); name = name.concat( Integer.toString(poolNum)); // Name assigning finishes myThreads[i].setNameOfThread(name); } // Creating new array of boolean type which is // referred by isUsed reference isUsed = new boolean[n]; for (int i = 0; i < n; i++) { // Now making isUsed false for all the // references false, // false because when initializing, no // reference from outside is referring to // any of the objects created (from o to // size-1) isUsed[i] = false; } status = true; } return status; } // Method 2 // To get reference of the Thread Objects Present in the // Pool If no object is free, it returns null public Thread getReference() { Thread threadToReturn = null; if (ThreadreferenceCount < n) { for (int i = 0; i < n; i++) { // When no reference from outside the class // is referring to object myThread[i], // isUsed[i] is false if (false == isUsed[i]) { threadToReturn = myThreads[i]; // Make isUsed[i] as true because we are // returning a reference to the object // referred by myThread[i] isUsed[i] = true; // Incrementing the count because we are // returning a reference to the object // referred by myThread[i] to outside // world now this object cant be referred // by another reference from outside ThreadreferenceCount++; // Break keyword break; } } } return threadToReturn; } // Method 3 // To release the outside world reference; // Here : "thread" - passed as parameter public void releaseReference(Thread thread) { if (ThreadreferenceCount > 0) { for (int i = 0; i < n; i++) { // Compare the "thread" parameter with every // reference and release the matched one by // making isUsed[i] = false; if (true == thread.compare(myThreads[i])) { // Make isUsed[i] is false to show no // reference from // outside the class is referring to // object myThread[i] isUsed[i] = false; // Decrementing the count because we are // releasing a reference to the object // in outside world ThreadreferenceCount--; break; } } } } // Method 4 // To make all the objects free for garbage collection // To restore to initial situation public boolean deInitialize() { boolean status = false; if (isFirst = false) { status = true; } // This condition is not required if one wants to // deinitialize() even if the references are present // outside else if (ThreadreferenceCount == 0) { for (int i = 0; i < n; i++) { myThreads[i] = null; } myThreads = null; isUsed = null; n = 0; isFirst = true; status = true; } return status; } } // Class 3 // Min class public class Main { // Main driver method public static void main(String[] args) { // Display message on console for better readability System.out.println( "*****************POOL1 Of Threads Created*****************"); // Creating object of class 2 in class 3 main() // method ThreadPool p1 = new ThreadPool(); // Creating pool of 2 objects if (p1.initialize(2)) { System.out.println("Pool 1 initialized"); } else { System.out.println("Pool 1 not initialized"); } // Now getting 2 references to the 2 Objects from // this pool // Thread 1 Thread t1 = p1.getReference(); if (t1 != null) { System.out.println(t1.getNameOfThread()); } else { System.out.println( " t1 do not refer any object"); } // Thread 2 Thread t2 = p1.getReference(); if (t2 != null) { System.out.println(t2.getNameOfThread()); } else { System.out.println( " t2 do not refer any object"); } // Thread 3 Thread t3 = p1.getReference(); if (t3 != null) { System.out.println(t3.getNameOfThread()); } else { System.out.println( " t3 do not refer any object"); } // Releasing all the references of pool 1 p1.releaseReference(t1); t1 = null; p1.releaseReference(t2); t2 = null; // As we have not used deInitialize() method, we // cannot initialize the pool p1 again if (p1.initialize(2)) { // Print statement System.out.println("Pool 1 initialized"); } else { // Print statement System.out.println( "Pool 1 not initialized as it was already initialized\n"); } // Creating pool 2 // Display message on console for better readability System.out.println( "*****************POOL2 Of Threads Created*****************"); ThreadPool p2 = new ThreadPool(); // Creating pool of 3 objects p2.initialize(3); Thread tp1 = p2.getReference(); if (tp1 != null) { System.out.println(tp1.getNameOfThread()); } else { System.out.println( "tp1 dont refer to any object"); } // Releasing references of pool 2 p2.releaseReference(tp1); tp1 = null; // Deinitializing both the pools // using deInitialize() method p1.deInitialize(); p2.deInitialize(); } }
*****************POOL1 Of Threads Created***************** Pool 1 initialized 1 is the thread number of the pool 1 2 is the thread number of the pool 1 t3 do not refer any object Pool 1 not initialized as it was already initialized *****************POOL2 Of Threads Created***************** 1 is the thread number of the pool 2
Explicación de salida:
- Aquí, creamos dos grupos de objetos de subprocesos mediante:
ThreadPool p1 = new ThreadPool() & ThreadPool p2 = new ThreadPool()
- Luego llamamos al método initialize() en p1 y p2 dando tamaño (objetos «Subproceso» totales en el grupo) – 2 y 3 respectivamente.
- Luego, se crean 2 referencias de la clase Thread (t1 y t2) que hacen referencia a objetos (de tipo Thread) en Pool p1.
- Se crea una tercera referencia (t3) de la clase Thread, y estamos tratando de obtener Object (llamando a getReference() en p1) del grupo p1 para que t3 pueda referirlo. Pero t3 no se refiere a ningún objeto ya que el tamaño de Pool p1 es 2, solo 2 referencias del mundo exterior pueden referirse a los 2 objetos en el pool.
- Luego liberamos ambas referencias (t1 y t2) llamando al método releaseReference(). Ahora los objetos en el grupo están disponibles y las referencias del mundo exterior pueden referirse a ellos llamando al método getReference() en p1.
- De manera similar, creamos otra referencia (tp1) pero se refiere al objeto Thread contenido en el grupo p2 como llamamos al método getReference() en p2.
- Luego liberamos las referencias (tp1) llamando al método releaseReference().
- Al final, llamamos al método deInitialize() en p1 y p2 para devolver el grupo de p1 y p2 a la condición inicial que tenía antes de llamar a initialize().
Publicación traducida automáticamente
Artículo escrito por sameekshakhandelwal1712 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA