Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Build your own ObjectPool in Java to boost app speed

Increase the speed of your applications while reducing memory requirements

  • Print
  • Feedback
When I first implemented object pooling (specifically for database connections) into a realtime, multiuser application, average transaction times dropped from 250 milliseconds to 30 milliseconds. Users actually noticed and commented on the drastic increase in performance.

The idea of object pooling is similar to the operation of your local library. When you want to read a book, you know that it's cheaper to borrow a copy from the library rather than purchase your own copy. Likewise, it is cheaper (in relation to memory and speed) for a process to borrow an object rather than create its own copy. In other words, the books in the library represent objects and the library patrons represent the processes. When a process needs an object, it checks out a copy from an object pool rather than instantiate a new one. The process then returns the object to the pool when it is no longer needed.

There are, however, a few minor distinctions between object pooling and the library analogy that should be understood. If a library patron wants a particular book, but all the copies of that book are checked out, the patron must wait until a copy is returned. We don't ever want a process to have to wait for an object, so the object pool will instantiate new copies as necessary. This could lead to an exhoribitant amount of objects lying around in the pool, so it will also keep a tally on unused objects and clean them up periodically.

My object pool design is generic enough to handle storage, tracking, and expiration times, but instantiation, validation, and destruction of specific object types must be handled by subclassing.

Now that the basics out of the way, lets jump into the code. This is the skeletal object:

public abstract class ObjectPool 
{
   private long expirationTime;   
   private Hashtable locked, unlocked;        
   abstract Object create();
   abstract boolean validate( Object o );
   abstract void expire( Object o );
   synchronized Object checkOut(){...}
   synchronized void checkIn( Object o ){...}
}


Internal storage of the pooled objects will be handled with two Hashtable objects, one for locked objects and the other for unlocked. The objects themselves will be the keys of the hashtable and their last-usage time (in epoch milliseconds) will be the value. By storing the last time an object was used, the pool can expire it and free up memory after a specied duration of inactivity.

Ultimately, the object pool would allow the subclass to specify the initial size of the hashtables along with their growth rate and the expiration time, but I'm trying to keep it simple for the purposes of this article by hard-coding these values in the constructor.

ObjectPool()
{
   expirationTime = 30000; // 30 seconds
   locked = new Hashtable();         
   unlocked = new Hashtable();
}


The checkOut() method first checks to see if there are any objects in the unlocked hashtable. If so, it cycles through them and looks for a valid one. Validation depends on two things. First, the object pool checks to see that the object's last-usage time does not exceed the expiration time specified by the subclass. Second, the object pool calls the abstract validate() method, which does any class-specific checking or reinitialization that is needed to re-use the object. If the object fails validation, it is freed and the loop continues to the next object in the hashtable. When an object is found that passes validation, it is moved into the locked hashtable and returned to the process that requested it. If the unlocked hashtable is empty, or none of its objects pass validation, a new object is instantiated and returned.

  • Print
  • Feedback

Resources