Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Generic Object Pool in Java [Snippet]

DZone's Guide to

Generic Object Pool in Java [Snippet]

We have a quick look at how to implement a lightweight generic object pool in this post. Read on to have a look at the code.

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

I recently had to create a generic object pool with minimalistic code. I didn’t want to add too much load by adding third-party JARs. Moreover, I wanted code that can be applied to the creation of any objects. Below is my implementation of bounded Object Pool:

package com.linkwithweb.products.daolayer;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @author ashwinrayaprolu
*
* @param <T>
*/
public abstract class ObjectPool<T> {
  private Queue<T> pool;

  /**
  * Stores number of connections that are being used
  */
  private final AtomicInteger usageCount = new AtomicInteger(0);
  // Maximum number of connections that can be open. Defaulted to 20
  private int maxConnections = 20;

  private ScheduledExecutorService executorService;

  /**
  * Creates the pool.
  *
  * @param minIdle
  * minimum number of objects residing in the pool
  */
  public ObjectPool(final int minIdle,final int maxConnections) {
    // initialize pool
    this.maxConnections = maxConnections;
    initialize(minIdle);
  }

  /**
  * Creates the pool.
  *
  * @param minIdle
  * minimum number of objects residing in the pool
  * @param maxIdle
  * maximum number of objects residing in the pool
  * @param validationInterval
  * time in seconds for periodical checking of minIdle / maxIdle
  * conditions in a separate thread.
  * When the number of objects is less than minIdle, missing
  * instances will be created.
  * When the number of objects is greater than maxIdle, too many
  * instances will be removed.
  */
  public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval,final int maxConnections) {
    this.maxConnections = maxConnections;
    // initialize pool
    initialize(minIdle);

    // check pool conditions in a separate thread
    executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleWithFixedDelay(new Runnable() {

    @Override
    public void run() {
      int size = pool.size();
      if (size < minIdle) {
        if(usageCount.compareAndSet(maxConnections, maxConnections)){
          return;
        }

        int sizeToBeAdded = minIdle - size;

        for (int i = 0; i < sizeToBeAdded; i++) {
          System.out.println("Background Thread Creating Objects");
          pool.add(create());
        }
      } else if (size > maxIdle) {

        int sizeToBeRemoved = size - maxIdle;

        for (int i = 0; i < sizeToBeRemoved; i++) {
          System.out.println("Background Thread dumping Objects");
          pool.poll();
        }

      }

    }

    }, validationInterval, validationInterval, TimeUnit.SECONDS);

  }

  /**
  * Gets the next free object from the pool. If the pool doesn't contain any
  * objects,
  * a new object will be created and given to the caller of this method back.
  *
  * @return T borrowed object
  */
  public T borrowObject() {
    T object;

    if(usageCount.compareAndSet(maxConnections, maxConnections)){
      return null;
    }

    int preBorrowCount = usageCount.get();

    if ((object = pool.poll()) == null) {
      object = create();
    }

    while (usageCount.compareAndSet(preBorrowCount, preBorrowCount+1));

    return object;
  }

  /**
  * Returns object back to the pool.
  *
  * @param object
  * object to be returned
  */
  public void returnObject(T object) {
    if (object == null) {
    return;
    }

    int preReturnCount = usageCount.get();
    this.pool.offer(object);

    while (usageCount.compareAndSet(preReturnCount, preReturnCount-1));
  }

  /**
  * Shutdown this pool.
  */
  public void shutdown() {
    if (executorService != null) {
      executorService.shutdown();
    }
  }

  /**
  * Creates a new object.
  *
  * @return T new object
  */
  protected abstract T create();

  protected abstract void close(T object);

  private void initialize(final int minIdle) {
    pool = new ConcurrentLinkedQueue<T>();

    for (int i = 0; i < minIdle; i++) {
      pool.add(create());
    }
  }

}
Topics:
java ,object pool in java ,code ,implementation

Published at DZone with permission of Ashwin Rayaprolu, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}