Creating Multiple Pools of Objects of Variable Size in Java - GeeksforGeeks

15 Sep, 2021
Object pool pattern is a software creational design pattern that is used in situations where the cost of initializing a class instance is very high. Basically, an Object pool is a container that contains some amount of objects. So, when an object is taken from the pool, it is not available in the pool until it is put back. Objects in the pool have a lifecycle: 
Creation
Validation
Destroy.
Object pooling can provide a large speed improvement; it works best when the cost of initializing a class instance is high, the pace of instantiation is high, and the number of instantiations in use at any given moment is low.The Object Pool design is useful when objects are expensive to construct and only need to be used for a short period of time. In this design pattern, we keep track of which instantiated objects are in use and which are accessible.
How to create Multiple pools of Objects?
We all know how to create a single pool of objects. But there may be a requirement to create multiple pools of objects of variable size. This means instead of creating a single pool of objects o fixed size, we can have multiple pools & each pool has a different number of total objects.
What is the real-time requirement for it?
Memory allocation as needed for error handling or in emergent scenarios in programming can be accomplished by generating multiple variable-size memory pools.
There are a few objects for which the production of a new object appears to be slightly more expensive since they are not considered lightweight. Database connection objects, parser objects, thread generation, and so forth are examples. We may have to construct numerous such pools of objects in any application. Because the generation of such objects is expensive, it will have a negative impact on the performance of any program. We can use the same object again & again.
Implementation:We are here creating a class “Thread” whose Objects are there in pools & another class “ThreadPool” that is used to create multiple pools of “Thread” Objects.
In our class Thread class(class 1)
We have data members:
“uniqueId” Stores unique id generated for each thread object.
“name” Keeps the name for the thread object.
In our class ThreadPool class(class 2)
We have data members:
isFirst = true to keep true initially & whenever 1st Thread object in pool is created, after 1st object creation, it is set to false.
myThreads[] of type Thread which is an array reference that will refer to the Thread Class object(Thread Pool Array)
isUsed[]  of type boolean which is an array to Keep track that which Thread’s objects are in use currently
noOfThreadPools  to keep count of no of Thread Pools & is a class level Property
ThreadreferenceCount  to keep count of no of thread references in a particular pool
poolNum to store unique number given to every Pool Created
Example
Java
// Java Program to Creating Multiple Pools Of Objects of// Variable Size // Importing required classesimport java.io.*;import java.util.*; // Class 1// Helper classclass 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 classclass 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 classpublic 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

Output explanation: 
Here, we create two pools of Thread Objects by:
ThreadPool p1 = new ThreadPool() & ThreadPool p2 = new ThreadPool() 
Then we called initialize() method on p1 & p2 giving size (total “Thread” Objects in the pool ) – 2 & 3 respectively.
Then 2 references of Thread class ( t1 & t2) are created who are referencing Objects (of Thread type) in Pool p1.
A 3rd  reference(t3) of Thread class is created, and we are trying to get Object (by calling getReference() on p1)from pool p1 so that t3 can refer it. But t3 do not refer to any object as Pool p1 size is 2, only 2 references from the outside world can refer to the 2 objects in the pool.
Then we release both the references (t1 & t2) by calling the method releaseReference(). Now the objects in the pool are available & the outside world references can refer them by calling the method getReference() on p1.
Similarly, we created another reference (tp1) but it refers to the Thread object contained in the pool p2 as we called the method getReference() on p2.
Then we release the references (tp1) by calling the method releaseReference().
At the end we call method deInitialize() on p1 & p2 bring back p1 & p2 pool to the starting condition that was before calling initialize(). 
arorakashish0911
simranarora5sos
anikaseth98
Java-Class and Object
Java
Java-Class and Object
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Different ways of Reading a text file in Java
Constructors in Java
Stream In Java
Generics in Java
Exceptions in Java
Functional Interfaces in Java
Comparator Interface in Java with Examples
HashMap get() Method in Java
Strings in Java
StringBuilder Class in Java with Examples