介绍
结合http://my.oschina.net/chengxiaoyuan/blog/607276 概念一节的分析,commons-pool2中以三个接口展开,它们分别有自己的实现,其中部分类图如下:
具体分析
对象池
1. ObjectPool的实现:
SoftReferenceObjectPool,该池中的对象都被SoftReference包装,该对象运行jvm在需要垃圾回收时回收引用的对象的,它没有Evictor驱逐机制,靠jvm自身的垃圾回收。
GenericObjectPool,最常用的对象池,有自己的Evictor驱逐机制
2. KeyedObjectPool的实现
GenericKeyedObjectPool,跟GenericObjectPool类似,只是多了分组机制。
池对象
PooledObject提供一个默认实现DefaultPooledObject,这个包装器用来跟踪一些额外信息,比如对象状态
PooledSoftReference继承自DefaultPooledObject,只是它里面是用SoftReference做软连接,jvm在内存不足时可以直接回收。
对象工厂
PooledObjectFactory接口定义了创建、激活、验证、钝化、销毁接口,这个一般使用者自定义实现这些方法。可以参考 中TSocketFactory的实现。
核心代码
SoftReferenceObjectPool:
//借出对象 public synchronized T borrowObject() throws Exception { assertOpen();//确定池是打开的 T obj = null; boolean newlyCreated = false; PooledSoftReferenceref = null; while (null == obj) { if (idleReferences.isEmpty()) { if (null == factory) { throw new NoSuchElementException(); } else { //如果空闲列表为空则创建 newlyCreated = true; obj = factory.makeObject().getObject(); createCount++; // Do not register with the queue // 弱引用 ref = new PooledSoftReference (new SoftReference (obj)); allReferences.add(ref);//加入所有列表 } } else { //如果空闲列表不为空则直接获取 ref = idleReferences.pollFirst(); obj = ref.getObject(); // Clear the reference so it will not be queued, but replace with a // a new, non-registered reference so we can still track this object // in allReferences ref.getReference().clear();//清除之后重新引用 ref.setReference(new SoftReference (obj)); } if (null != factory && null != obj) { try { factory.activateObject(ref);//激活 if (!factory.validateObject(ref)) {//验证 throw new Exception("ValidateObject failed"); } } catch (Throwable t) { PoolUtils.checkRethrow(t); try { destroy(ref);//销毁 } catch (Throwable t2) { PoolUtils.checkRethrow(t2); // Swallowed } finally { obj = null; } if (newlyCreated) { throw new NoSuchElementException( "Could not create a validated object, cause: " + t.getMessage()); } } } } numActive++; ref.allocate();//切换状态 return obj; } //返回对象 public synchronized void returnObject(T obj) throws Exception { boolean success = !isClosed(); final PooledSoftReference ref = findReference(obj);//查询该对象的引用 if (ref == null) { throw new IllegalStateException( "Returned object not currently part of this pool"); } if (factory != null) { if (!factory.validateObject(ref)) {//验证 success = false; } else { try { factory.passivateObject(ref);//钝化 } catch (Exception e) { success = false; } } } boolean shouldDestroy = !success; numActive--; if (success) {//如果对象合格 // Deallocate and add to the idle instance pool ref.deallocate();//切换状态 idleReferences.add(ref);//放到空闲池 } notifyAll(); // numActive has changed if (shouldDestroy && factory != null) { try { destroy(ref); } catch (Exception e) { // ignored } } }
2. GenericObjectPool
//获取对象 public T borrowObject(long borrowMaxWaitMillis) throws Exception { assertOpen();//确定池子已经打开 //获取对象的时候做一些检查 AbandonedConfig ac = this.abandonedConfig; if (ac != null && ac.getRemoveAbandonedOnBorrow() && (getNumIdle() < 2) && (getNumActive() > getMaxTotal() - 3) ) { removeAbandoned(ac); } PooledObjectp = null; // Get local copy of current config so it is consistent for entire // method execution boolean blockWhenExhausted = getBlockWhenExhausted();//池对象耗尽之后是否阻塞 boolean create; long waitTime = System.currentTimeMillis(); while (p == null) { create = false; if (blockWhenExhausted) {//如果阻塞式获取 p = idleObjects.pollFirst();//先取一个 if (p == null) { p = create();//如果为空则创建 if (p != null) { create = true; } } if (p == null) {//如果上面没有获取到对象 if (borrowMaxWaitMillis < 0) { p = idleObjects.takeFirst();//一直等待 } else { //按指定的超时时间等待 p = idleObjects.pollFirst(borrowMaxWaitMillis, TimeUnit.MILLISECONDS); } } if (p == null) { throw new NoSuchElementException( "Timeout waiting for idle object"); } if (!p.allocate()) {//改变状态 p = null; } } else { //非阻塞式获取 p = idleObjects.pollFirst();//先取第一个 if (p == null) { p = create();//没取到则创建 if (p != null) { create = true; } } if (p == null) { throw new NoSuchElementException("Pool exhausted"); } if (!p.allocate()) {//改变状态 p = null; } } if (p != null) { try { //如果对象不为空则激活 factory.activateObject(p); } catch (Exception e) { try { destroy(p);//激活失败就销毁 } catch (Exception e1) { // Ignore - activation failure is more important } p = null; if (create) { NoSuchElementException nsee = new NoSuchElementException( "Unable to activate object"); nsee.initCause(e); throw nsee; } } //验证对象 if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) { boolean validate = false; Throwable validationThrowable = null; try { validate = factory.validateObject(p); } catch (Throwable t) { PoolUtils.checkRethrow(t); validationThrowable = t; } if (!validate) { try { destroy(p);//验证失败就销毁 destroyedByBorrowValidationCount.incrementAndGet(); } catch (Exception e) { // Ignore - validation failure is more important } p = null; if (create) { NoSuchElementException nsee = new NoSuchElementException( "Unable to validate object"); nsee.initCause(validationThrowable); throw nsee; } } } } } updateStatsBorrow(p, System.currentTimeMillis() - waitTime);//更新borrow的统计信息 return p.getObject(); } //回收对象 public void returnObject(T obj) { PooledObject p = allObjects.get(new IdentityWrapper (obj));//取出该对象在池中的引用 if (p == null) { if (!isAbandonedConfig()) { throw new IllegalStateException( "Returned object not currently part of this pool"); } else { return; // Object was abandoned and removed } } synchronized(p) { final PooledObjectState state = p.getState();//根据状态判断该对象是否已经还回过 if (state != PooledObjectState.ALLOCATED) { throw new IllegalStateException( "Object has already been returned to this pool or is invalid"); } else { p.markReturning(); // Keep from being marked abandoned } } long activeTime = p.getActiveTimeMillis(); if (getTestOnReturn()) {//返回验证 if (!factory.validateObject(p)) { try { destroy(p); } catch (Exception e) { swallowException(e); } try { ensureIdle(1, false); } catch (Exception e) { swallowException(e); } updateStatsReturn(activeTime); return; } } try { factory.passivateObject(p);//钝化对象 } catch (Exception e1) { swallowException(e1); try { destroy(p); } catch (Exception e) { swallowException(e); } try { ensureIdle(1, false); } catch (Exception e) { swallowException(e); } updateStatsReturn(activeTime); return; } if (!p.deallocate()) { throw new IllegalStateException( "Object has already been returned to this pool or is invalid"); } int maxIdleSave = getMaxIdle(); if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) { try { destroy(p);//如果该对象不符合一些条件就销毁,池关闭或者空闲对象数已满 } catch (Exception e) { swallowException(e); } } else { if (getLifo()) {//根据先进先出、后进先出存入对象 idleObjects.addFirst(p); } else { idleObjects.addLast(p); } if (isClosed()) { // Pool closed while object was being added to idle objects. // Make sure the returned object is destroyed rather than left // in the idle object pool (which would effectively be a leak) clear(); } } updateStatsReturn(activeTime); }
3. GenericKeyedObjectPool和GenericObjectPool类似