Pool在N多环境下碰到,比如连接池、线程池、缓存池...
当某一对象从池中取得,那只有等待被用完放回去以后,其它的线程才能再次从池中获取。对象在池中是具有自己生命周期:创建、验证、使用、销毁等等。Pool的方式也许是最好的方式用来管理同一的资源。
运用的场景:
高频率的运用同一的资源
对象大且很消耗内存(DB连接)
需要长时间的初始化
IO消耗大
对象非线程安全
Apache Commons Pool 提供其轻量级的作用,不过它并未使用JDK1.5之后的Execute的框架,这是我觉得可能比较可惜的,就如同Proxool跟Boncp比较,性能指标提升最大一个就是分区和使用Execute、Guava等性能提升比较大的工具包。
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public abstract class ObjectPool<T> {
private ConcurrentLinkedQueue<T> pool;
private ScheduledExecutorService executorService;
/**
* Creates the pool.
*
* @param minIdle
* 初始化最小的对象池中对象创建数量
*/
public ObjectPool(final int minIdle) {
// initialize pool
initialize(minIdle);
}
/**
* Pool创建
*
* @param minIdle
* 最小的数量
* @param maxIdle
* 最大数量
* @param validationInterval
* 检查最大/最小的池中的对象的频率
*/
public ObjectPool(final int minIdle, final int maxIdle,
final long validationInterval) {
// 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) {
int sizeToBeAdded = minIdle - size;
for (int i = 0; i < sizeToBeAdded; i++) {
pool.add(createObject());
}
} else if (size > maxIdle) {
int sizeToBeRemoved = size - maxIdle;
for (int i = 0; i < sizeToBeRemoved; i++) {
pool.poll();
}
}
}
}, validationInterval, validationInterval, TimeUnit.SECONDS);
}
/**
* 获取对象,如果没有,那就创建且返回
*
* @return T borrowed object
*/
public T borrowObject() {
T object;
if ((object = pool.poll()) == null) {
object = createObject();
}
return object;
}
/**
* Returns object back to the pool.
*
* @param object
* object to be returned
*/
public void returnObject(T object) {
if (object == null) {
return;
}
this.pool.offer(object);
}
/**
* Shutdown this pool.
*/
public void shutdown() {
if (executorService != null) {
executorService.shutdown();
}
}
/**
* Creates a new object.
*
* @return T new object
*/
protected abstract T createObject();
private void initialize(final int minIdle) {
pool = new ConcurrentLinkedQueue<T>();
for (int i = 0; i < minIdle; i++) {
pool.add(createObject());
}
}
}
抽象池中主要提供borrowObject 是在具体实现类中可存放任意的对象,附件中存有测试代码。