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 是在具体实现类中可存放任意的对象,附件中存有测试代码。