Saturday, May 18, 2013

How to create Object Pools in JAVA


Note: For simplicity sake I have taken User object as an example.In real world one should consider pooling when object creation is considered costly. For example database connections
Object pool is a set of ready to use objects. Clients can borrow the object from the pool and the object will be returned back to the pool when done so that it can be reused. Data base connection pool is a well-known example of object pooling. Creating our own object pooling will usually take more resources as one has to concentrate on thread safety and one bag full of test cases for the pool.
Apache commons pool hides the complexity of implementing the pool and has nice set of factories through which we can define the life cycle methods of the pool which are to be pooled. More information on apache’s common pool can be found at http://commons.apache.org/proper/commons-pool/.
This post shows how to create object pool using apache’s common pool. Many websites allows users to register, login and logout features. First thing which strikes my mind is 90% of time developers will write an object to hold the user information.  If the unknown website we are talking about gets one lakh login requests we will end up creating one lakh user objects. Google this “why is object creation costly”, you will get handful of results saying why object creation is a costly operation. Instead of creating User object every time in our unknown website we can create an object pool with a set of pre initialized User objects. By doing this may be the application will be much faster in serving the requests and more efficient. Enough said already lets jump into the example
While creating object pool using apache’s common pool first thing we can do is create a factory class to create our objects which are to be pooled.  org.apache.commons.pool.BasePoolableObjectFactory will be the parent class for our factory. BasePoolableObjectFactory has lifecycle methods for the objects which are to be pooled. Below are the lifecycle methods
makeObject : called to create new instances which are to be pooled
activateObject: called before borrowing the object from pool
validateObject: called to validate object before retrieving and returning the object to the pool
passivateObject: called before returning the object to pool. We can use this method to do some clean up
destroyObject:called when the object is removed from pool for good.
package blog.itsvenkis.object.pool.factory;

import org.apache.commons.pool.BasePoolableObjectFactory;

import blog.itsvenkis.object.pool.domain.Poolable;

/**
 * @author itsvenkis
 *         A factory class which creates objects which are 
 *         in turn used by object pooling. Provides life cycle methods 
 *         of the object which is to be pooled. Objects created by 
 *         this factory are required to implement {@link blog.itsvenkis.object.pool.domain.Poolable}
 *         
 * @see org.apache.commons.pool.PoolableObjectFactory
 * @see org.apache.commons.pool.BasePoolableObjectFactory
 *
 */
@SuppressWarnings("unchecked")
public class ObjectPoolFactory extends BasePoolableObjectFactory{

    private final Class poolableObj;
    
    protected Class getPoolableObject(){
        return poolableObj;
    }
    
    //Use static factory method instead
    protected ObjectPoolFactory(Class poolableObj){
        this.poolableObj = poolableObj;
    }
    
    //Static factory method to create instance of this factory.
    public static ObjectPoolFactory newInstance(String className) throws ClassNotFoundException{
        Class poolObj= (Class) Class.forName(className);
        ObjectPoolFactory factory = new ObjectPoolFactory(poolObj);
        return factory;
    }
    
    @Override
    /**
     * called whenever an new instance is needed
     * @see org.apache.commons.pool.PoolableObjectFactory#makeObject
     */
    public Object makeObject() throws Exception {
        return poolableObj.newInstance();
    }
    
    /**
     * invoked on every instance when it is returned to the pool.
     * @see org.apache.commons.pool.PoolableObjectFactory#makeObject
     */
    public void passivateObject(Object obj) {
        if(obj instanceof Poolable){
            Poolable poolObj= (Poolable) obj;
            poolObj.clear();
        }else{
            throw new RuntimeException("Object has to be instance of Poolable");
        }
    }
    
    public boolean validateObject(Object obj){
        if(obj instanceof Poolable){
            return true;
        }
        return false;
    }

}
Next, create a service to retrieve and return the objects to the pool
package blog.itsvenkis.object.pool;

import org.apache.commons.pool.impl.StackObjectPool;

/**
 * @author itsvenkis
 * 
 *         This class provides operations to retrieve and return User objects
 *         to the object pool. The original pool itself is injected by spring 
 *         configuration file.
 *
 */
public class UserService {
 
 //pool of User objects. 
 private StackObjectPool userObjectPool;// Why isn't this a generic? can avoid unnecessary casting
 
 //getter
 public StackObjectPool getUserObjectPool() {
  return userObjectPool;
 }
 
 //setter
 public void setUserObjectPool(StackObjectPool userObjectPool) {
  this.userObjectPool = userObjectPool;
 }
 
 /**
  * 
  * @return IUser
  *         User object from object pool
  *         
  * @throws Exception
  */
 public User newUser() throws Exception {
  return (User) userObjectPool.borrowObject();
 }
 
 /**
  * 
  * @param user
  *     The user object which is to be returned to pool.
  *        Only objects retrieved using @{link {@link #newUser()}
  *        can be returned to the pool.
  * @throws Exception
  */
 public void returnUser(User user) throws Exception{
  userObjectPool.returnObject(user);
 } 
} 
  Declare the object pool as spring beans 

  
  

 

      
       blog.itsvenkis.object.pool.User
      

     

      
      
      
       20
      

Source code: github
Dear Readers, kindly like us on facebook to see whats happening on this blog

No comments:

Post a Comment