对象池模式 一种特殊的工厂对象,一个对象池包含一组已经初始化过且可以使用的对象。用户可以从池中取得对象,并对其进行操作,在不需要的时候将其归还给对象池。
使用对象池的目的是为了提升性能,当需要创建比较耗费时间的对象时尤为明显。
角色和职责 对象池的管理者 管理者来维护对象池,包括初始化对象池、扩充对象池的大小、获取对象时的策略、重置归还对象的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public  class  PoolMgr     private  int  init ;     private  int  max;     private  int  factor;     private  Colection c;      public  void  init ()                 }               public  Object aquire ()          return  c.remove();     }     public  void  release (Object o)          if (o == null ) return ;         reset(o);         c.add(o);     } } 
对象池的使用者 使用者从管理者处获取对象,使用完成后必须归还对象避免一致占用。
1 2 3 4 5 6 Object o = null ; try {   o = PoolMgr.getInstance();   }finaly{    PoolMgr.release(o);   } 
优点 复用池中的对象,消除创建/回收对象所产生的内存开销,CPU开销以及IO开销。
缺点 多线程并发环境中,需要考虑线程安全问题,需要在数据结构上进行同步或者为锁竞争产生阻塞,这种开销处理不好会比创建销毁独享的开销高很多。
Common Pool2 Commons Pool2核心部分由三个基础接口和相关的实现类实现:
PooledObject 池化对象,对池中的对象进行封装,封装对象的状态和一些其他信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public  interface  PooledObject <T > extends  Comparable <PooledObject <T >>          T getObject ()  ;          long  getCreateTime ()           long  getActiveTimeMillis ()           long  getIdleTimeMillis ()           long  getLastBorrowTime ()           long  getLastReturnTime ()           long  getLastUsedTime ()           void  invalidate ()           void  use ()           PooledObjectState getState ()  ;          void  markAbandoned ()           void  markReturning ()  } 
PooledObjectFactory  池化对象工厂,负责对象的创建、初始化、销毁和验证工作,Factory对象由ObjectPool持有并使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  interface  PooledObjectFactory <T >          PooledObject<T> makeObject ()  throws  Exception ;          void  destroyObject (PooledObject<T> p)  throws  Exception          boolean  validateObject (PooledObject<T> p)           void  activateObject (PooledObject<T> p)  throws  Exception          void  passivateObject (PooledObject<T> p)  throws  Exception } 
ObjectPool  持有对象并提供取/还等操作.
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  public interface ObjectPool<T> {     // 从池中获取一个对象,客户端在使用完对象后必须使用 returnObject 方法返还获取的对象     T borrowObject() throws Exception, NoSuchElementException,             IllegalStateException;     // 将对象返还到池中。对象必须是从 borrowObject 方法获取到的     void returnObject(T obj) throws Exception;     // 使池中的对象失效,当获取到的对象被确定无效时(由于异常或其他问题),应该调用该方法     void invalidateObject(T obj) throws Exception;     // 池中当前闲置的对象数量     int getNumIdle();     // 当前从池中借出的对象的数量     int getNumActive();     // 清除池中闲置的对象     void clear() throws Exception, UnsupportedOperationException;     // 关闭这个池,并释放与之相关的资源     void close();     ... } 
对象池配置 对象池配置提供了对象池初始化所需要的参数,Common Pool2中的基础配置类时BaseObjectPoolConfig, 有GenericObjectPoolConfig和GenericKeyedObjectPoolConfig,分别为GenericObjectPool和GenericKeyedObjectPool使用。
参数 
解释 
默认值 
 
 
lifo 
连接池存放池对象的方式; true:放在空闲队列的嘴钱买呢, false:放在空闲队列的最后面 
true 
 
fairness 
从池中获取/返还对象时是否使用公平锁机制 
false 
 
maxWaitMillis 
获取资源的等待时间。blockWhenExhausted为true时有效。-1代表无时间限制,一致阻塞到有可用的资源 
 
minEvictableIdleTimeMillis 
对象空闲的最小时间,打到此值后空闲对象可能会被移除,-1表示不移除 
30分钟 
 
softMinEvictableIdletimeMillis 
对象空闲的最小时间,并且池中之少保留有minidle所指定的个数 
 
numTestsPerEvictionRun 
资源回收线程执行一次回收操作回收资源的个数 
3 
 
evictionPolicyClassName 
资源回收策略 
org.apache.commons.pool2.impl.DefaultEvictionPolicy 
 
testOnCreate 
创建对象时是否调用factory.validateObject 
false 
 
testOnBorrow 
获取对形势是否调用factory.validateObject 
false 
 
testOnReturn 
返还对象时是否调用factory.validateObject 
false 
 
timeBetweenEvictionRunsMills 
回收资源线程的执行周期,默认-1表示不启用回收资源线程 
-1 
 
blockWhenExhausted 
资源耗尽时,是否阻塞等待获取资源 
true 
 
testWhileIdel 
池中的限制对象是否由逐出器验证,无法验证的对象将从池中删除销毁 
false 
 
池化对象的状态 
参数值 
描述 
 
 
IDEL 
在池中,处于空闲状态 
 
ALLOCATED 
被使用中 
 
EVICTION 
正在被逐出器验证 
 
VALIDAITTON 
正在验证 
 
INVALID 
驱逐测试或者验证失败并将被销毁 
 
ABANDONED 
对象被客户端拿出后,长时间未返回池中,或者没有调用use方法,被标记为抛弃 
 
Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  class  StringBufferFactory  extends  BasePooledObjectFactory <StringBuffer >          @Override      public  StringBuffer create ()           return  new  StringBuffer();     }          @Override      public  PooledObject<StringBuffer> wrap (StringBuffer buffer)           return  new  DefaultPooledObject<>(buffer);     }          @Override      public  void  passivateObject (PooledObject<StringBuffer> pooledObject)           pooledObject.getObject().setLength(0 );     } } 
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43   GenericObjectPoolConfig config = new  GenericObjectPoolConfig(); PooledObjectFactory factory = new  StringBufferFactory(); ObjectPool<StringBuffer> pool = new  GenericObjectPool<>(factory, config); StringReader in = new  StringReader("abcdefg" ); StringBuffer buf = null ; try  {         buf = pool.borrowObject();          for  (int  c = in.read(); c != -1 ; c = in.read()) {         buf.append((char ) c);     }     return  buf.toString(); } catch  (Exception e) {     try  {                  pool.invalidateObject(buf);                  buf = null ;     } catch  (Exception ex) {              }     throw  e; } finally  {     try  {         in.close();     } catch  (Exception e) {              }     try  {         if  (null  != buf) {                          pool.returnObject(buf);         }     } catch  (Exception e) {              } } 
参考:Apache Common Pool2 对象池应用浅析 一个广为人知但鲜有人用的技巧:对象池