package com.jsonde.util.pool;
import java.lang.ref.SoftReference;
import java.lang.reflect.ParameterizedType;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
public class ObjectPool<T> {
private final Class<T> elementsClass;
private final Queue<SoftReference<T>> pool = new LinkedList<SoftReference<T>>();
private final Queue<T> persistentPool = new ArrayBlockingQueue<T>(4000);
@SuppressWarnings("unchecked")
protected ObjectPool() {
ParameterizedType genericSuperClass = (ParameterizedType)
getClass().getGenericSuperclass();
elementsClass = (Class<T>) genericSuperClass.getActualTypeArguments()[0];
}
public ObjectPool(Class<T> elementsClass) {
this.elementsClass = elementsClass;
}
public final synchronized void returnToPool(T element) {
passivate(element);
if (!persistentPool.offer(element) && pool.size() < 4000) {
pool.add(new SoftReference<T>(element));
}
}
protected void passivate(T element) {
}
protected void activate(T element) {
}
protected T create() throws ObjectPoolException {
try {
return elementsClass.newInstance();
} catch (InstantiationException e) {
throw new ObjectPoolException(e);
} catch (IllegalAccessException e) {
throw new ObjectPoolException(e);
}
}
public final synchronized T takeFromPool() throws ObjectPoolException {
T element = takeFromPoolOrCreateImpl();
activate(element);
return element;
}
private T takeFromPoolOrCreateImpl() throws ObjectPoolException {
T element;
if (null != (element = persistentPool.poll())) {
return element;
}
while (!pool.isEmpty()) {
SoftReference<T> elementReference = pool.poll();
if (null != (element = elementReference.get())) {
activate(element);
return element;
}
}
return create();
}
}