I was looking for a Java solution for Object Pool implementation. Focus on high throughput and low latency, especially under multiple thread i.e. high concurrency environment.
Below are possible solutions that I am looking at:
- Apache Commons ObjectPool
- Implementation with Java ConcurrentLinkedQueue
- Furious ObjectPool
- Implementation with Java LinkedBlockingQueue
- Implementation with Java BlockingQue
Implementation with Java ConcurrentLinkedQueue:
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
*
* Implementation with Java ConcurrentLinkedQueue
*
* @author stones333
*
*/
final public class PoolWithConcurrentLinkedQueue<T> implements ObjectPoolInterface<T> {
public static interface ObjectPoolFactory<T>
{
public T create();
}
final private Queue<T> objects;
private ObjectPoolFactory<T> factory=null;
public PoolWithConcurrentLinkedQueue(ObjectPoolFactory<T> objFactory) {
this.factory = objFactory;
this.objects = new ConcurrentLinkedQueue<T>();
}
public PoolWithConcurrentLinkedQueue(ObjectPoolFactory<T> objFactory, long count) {
this.factory = objFactory;
this.objects = new ConcurrentLinkedQueue<T>();
for (long i=0; i<count; i++) {
objects.add( factory.create() );
}
}
public T addObject() {
T t = factory.create();
objects.add(t);
return t;
}
public T borrowObject() {
T t;
if ((t = objects.poll()) == null) {
t = factory.create();
objects.add(t);
}
return t;
}
public void returnObject(T object) {
this.objects.offer(object);
}
public int size() { return objects.size(); };
}
Implementation with Java LinkedBlockingQueue :
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
*
* Implementation with Java LinkedBlockingQueue
*
* @author stones333
*
*/
public class PoolWithLinkedBlockingQueue<T> implements ObjectPoolInterface<T> {
public static interface ObjectPoolFactory<T>
{
public T create();
}
final private LinkedBlockingQueue<T> objects;
private ObjectPoolFactory<T> factory=null;
public PoolWithLinkedBlockingQueue(ObjectPoolFactory<T> objFactory) {
this.factory = objFactory;
this.objects = new LinkedBlockingQueue<T>();
}
public PoolWithLinkedBlockingQueue(ObjectPoolFactory<T> objFactory, long count) {
this.factory = objFactory;
this.objects = new LinkedBlockingQueue<T>();
for (long i=0; i<count; i++) {
objects.add( factory.create() );
}
}
public T addObject() {
T t = factory.create();
objects.add(t);
return t;
}
public T borrowObject() {
T t;
if ((t = objects.poll()) == null) {
t = factory.create();
objects.add(t);
}
return t;
}
//
public void returnObject(T object) {
this.objects.offer(object);
}
public int size() { return objects.size(); };
}
Implementation with Java BlockingQue:
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
*
* Implementation with Java BlockingQueue
*
* @author stones333
*
*/
public final class PoolWithBlockingQue <T> implements ObjectPoolInterface<T> {
public static interface ObjectPoolFactory<T>
{
public T create();
}
private final BlockingQueue<T> objects;
private ObjectPoolFactory<T> factory = null;
public PoolWithBlockingQue(ObjectPoolFactory<T> objFactory) {
this.factory = objFactory;
this.objects = new LinkedBlockingQueue<T>();
}
public PoolWithBlockingQue(ObjectPoolFactory<T> objFactory, long count) {
this.factory = objFactory;
this.objects = new LinkedBlockingQueue<T>();
for (long i=0; i<count; i++) {
objects.add( factory.create() );
}
}
public PoolWithBlockingQue(ObjectPoolFactory<T> objFactory, Collection<? extends T> objects) {
this.factory = objFactory;
this.objects = new ArrayBlockingQueue<T>(objects.size(), false, objects);
}
public PoolWithBlockingQue(Collection<? extends T> objects) {
this(null, objects);
}
public T borrowObject() throws InterruptedException {
T t = this.objects.take();
if (t==null) {
t = (factory!=null) ? factory.create() : null;
if (t!=null) objects.add(t);
}
return t;
}
public void returnObject(T object) throws InterruptedException {
this.objects.put(object);
}
}
Java Test Code:
/**
*
* MultiThread Test code for Object Pool implementations
*
* @author stones333
*
*/
public class ObjectPoolTest {
private ObjectPoolInterface<StringBuffer> objectPool = null;
public ObjectPoolInterface<StringBuffer> getObjectPool() {
return objectPool;
}
public void setObjectPool(ObjectPoolInterface<StringBuffer> objectPool) {
this.objectPool = objectPool;
}
public Object fetchObject() throws RuntimeException, InterruptedException {
StringBuffer obj = objectPool.borrowObject();
objectPool.returnObject(obj);
return obj;
}
public Object fetchObjects() throws RuntimeException, InterruptedException {
Object obj = null;
for (int i=0; i<10000; i++) {
obj = fetchObject();
if (obj==null) {
throw new RuntimeException ("object from pool is null");
}
}
return obj;
}
}
MultiThread Test code for Object Pool implementation with LinkedBlockingQueue:
/**
*
* MultiThread Test code for Object Pool implementation with LinkedBlockingQueue
*
* @author stones333
*
*/
public class PoolWithLinkedBlockingQueueTest extends ObjectPoolTest {
public static class TestPoolFactory<T> implements PoolWithLinkedBlockingQueue.ObjectPoolFactory<T> {
@Override
public T create() {
StringBuffer obj = new StringBuffer();
return (T) obj;
}
}
static private ObjectPoolInterface<StringBuffer> objects = new PoolWithLinkedBlockingQueue<StringBuffer>( new TestPoolFactory<StringBuffer>(), 1000000);
public PoolWithLinkedBlockingQueueTest () {
super.setObjectPool(objects);
}
}
Test code for other Java Object Pool implementations are obvious and omitted here.

No comments:
Post a Comment