Interview Questions

Java Object Pooling

In this section let us discuss about object pooling in java. In the world of java programming, creation of any new object may sound costly depending on the nature of object and the resources it uses. It would be better if we can pool those objects and reuse the same. Creation should be done only when it is necessary. There may also be need to create only a fixed number of objects and reuse them without creating new objects more than the fixed limit.

Having said the above requirement there is a need to handle, how to know when the object is ready for reuse. We can handle that in a simple way programmatically.

Consider a scenario where there is a need to create only n(lets say 3) objects and reuse them. If the n objects are created and when a new request comes they should block until any one object is ready to be reused.

/**
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package in.techdive.java.examples;

import java.util.ArrayList;
import java.util.List;

public class ShareObject
{
    // status to programmatically check object is referred or not
    private boolean       isClosed = true;

    static int         reqCnt   = 0;

    static List<ShareObject> sOList   = new ArrayList<ShareObject>(3);

    public boolean isClosed()
    {
        return isClosed;
    }

    public void setClosed(boolean isClosed)
    {
        this.isClosed = isClosed;
    }

    private ShareObject()
    {
    }

    public synchronized static ShareObject getInstance()
    {
        reqCnt++;
        System.out.println("Request Count = " + reqCnt);
        boolean objReturned = false;
        if (sOList.size() > 0)
        {
            do
            {
                for (ShareObject sObj : sOList)
                {
                    if (sObj.isClosed())
                    {
                        sObj.setClosed(false);
                        objReturned = true;
                        return sObj;
                    }
                }
                if (sOList.size() == 3)
                {
                    try
                    {

                        Thread.sleep(2000);
                    }
                    catch (InterruptedException e)
                    {

                        e.printStackTrace();
                    }
                }
            }
            while ((!objReturned) && (sOList.size() == 3));
        }
        if ((!objReturned))
        {
            ShareObject sO = new ShareObject();
            sO.setClosed(false);
            sOList.add(sO);
            System.out.println(sOList.size() + " instance created");
            return sO;
        }
        return null;
    }

    public static void main(String[] args)
    {
        System.out.println("Object Pooling Demo Started\n");
        ShareObject s1 = null;
        for (int i = 0; i < 7; i++)
        {
            s1 = ShareObject.getInstance();
            if (i >= 2)
            {
                s1.setClosed(true);
            }
            try
            {
                Thread.sleep(200);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

Consider the Share Object class above. It has a boolean variable isClosed to verify whether an object is currently referred or not. The sOList list is used to hold the fixed number of objects created. This class uses a private constructor , so the objects of this class can only be created or retrieved through getInstance() method.

Take a closer look at the getInstance method. When there is a request for a new object, before creating a new object it checks whether there is any object already existing in the sOList list. If yes , then it checks whether any of the objects in the list is not referred and can be reused. If yes it then returns that object to be reused by the requesting client. If no, then it blocks until any of the client dereferences the object . Wait a minute! What is meant by dereferencing? Actually in terms of java memory management its quiet complex. But I have made it simple by using a boolean variable isClosed. If it is true then it means a client is referencing or using the object. Else it is free to be reused.

For testing purpose , we use the main method to call the getInstance() method in a for loop . From the output we see that only first 3 instances are created and then they are reused when during 4th, 5th and subsequent requests.

Output:

Object Pooling Demo Started

Request Count = 1
1 instance created
Request Count = 2
2 instance created
Request Count = 3
3 instance created
Request Count = 4
Request Count = 5
Request Count = 6
Request Count = 7

Object pooling helps us to optimize the use of objects in java application. Similar kind of technique is used int DB connection pooling and its a bit tricky as it involves more resources.