Object Pool Design Pattern

Object pool is a software creational design pattern which keeps pool of objects and returns object from there only.

When it is necessary to work with a large number of objects that are particularly expensive to instantiate and each object is only needed for a short period of time, the performance of an entire application may be adversely affected. An object pool design pattern may be deemed desirable in cases such as these.Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high and the rate of instantiation and destruction of a class is high – in this case objects can frequently be reused, and each reuse saves a significant amount of time.The object pool design pattern creates a set of objects that may be reused.

Object pool can solves object creation problems in two ways.

In first way,whenever an object is requested ,if object is available then it is returned and if object is not available new object is created.

In second way,whenever an object is requested,it is checked if an object is available,if available then object is returned if not exception may be thrown or application needs to wait for object to get free.In first case pool size is not fixed,and in second case pool size is fixed and it can behave like singleton as we are creating fixed no of objects and we will be using only those throughout the application.

Following is the code for case one:

Abstract Object Pool:

package com.dp.objectpool;

import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;

public abstract class ObjectPoolAbstract<T> {
    
    private int exipreTime;
    private ConcurrentHashMap<T,Long> locked,available;
    
    public ObjectPoolAbstract() {
        //object that is created will be available for 40 seconds after that it will be not used any more.
        exipreTime = 4000;
        locked = new ConcurrentHashMap<>();
        available = new ConcurrentHashMap<>();
    }

    //these methods are specific to concrete implementation and hence are kept as abstract
    protected abstract T create();
    public abstract boolean validate(T t);
    public abstract void expire(T t);
    
    public synchronized void checkIn(T t){
        locked.remove(t);
        available.put(t, System.currentTimeMillis());
    }
    
    public synchronized T checkOut(){
         T t = null;
        if(available.size() > 0){
             Enumeration<T> e = available.keys();
              while (e.hasMoreElements()) {
                  t = e.nextElement();
                    if ((System.currentTimeMillis() - available.get(t)) > exipreTime) {
                      // object has expired and will be removed from available map also because expire time has reach
                        //objects will remain in available map till expire time is not reached from last reference to the that objects
                      available.remove(t);
                      expire(t);
                      t = null;
                    } else {
                      if (validate(t)) {
                        available.remove(t);
                        locked.put(t, System.currentTimeMillis());
                        return (t);
                      } 
                      else {
                          // object failed validation
                          available.remove(t);
                          expire(t);
                          t = null;
                        }
                    }
            
              }
        }   
            t = create();
            locked.put(t, System.currentTimeMillis());
            return t;
    }
}



2.Concrete Implmentation of ObjectPool:

package com.dp.objectpool;

import java.io.IOException;
import java.net.Socket;

public class SocketPoolConcrete extends ObjectPoolAbstract<Socket>{
    
    private String server;
    private int portNo;
    public SocketPoolConcrete(String server,int portNo) {
        this.server = server;
        this.portNo = portNo;
    }
    @Override
    protected Socket create() {
        Socket socket = null;
        try {
            socket = new Socket(server,portNo);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        return socket;
    }
    @Override
    public boolean validate(Socket t) {
        return !((Socket)t).isClosed();
    }
    @Override
    public void expire(Socket t) {
        try {
            ((Socket)t).close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

}



3. Client 

package com.dp.objectpool;

import java.net.Socket;

public class Client {

    public static void main(String[] args) {
        //get client socket object to communicate with server at localhost:8080(to run this server socket must listens at localhost:8080)
        SocketPoolConcrete socketPool = new SocketPoolConcrete("Localhost",8080);
        Socket socket = socketPool.checkOut();
    
        /*.
         * 
         * do your task
        .*/
        
        socketPool.checkIn(socket);
    }
}


Comments