/** * Obtains an instance from this pool. */ T borrowObject()throws Exception, NoSuchElementException, IllegalStateException;
/** * Returns an instance to the pool. By contract, <code>obj</code> */ voidreturnObject(T obj)throws Exception;
/** * Invalidates an object from the pool. */ voidinvalidateObject(T obj)throws Exception;
/** * Creates an object using the PooledObjectFactory or other * implementation dependent mechanism, passivate it, and then place it in * the idle object pool. */ voidaddObject()throws Exception, IllegalStateException ,UnsupportedOperationException;
/** * Returns the number of instances currently idle in this pool. */ intgetNumIdle();
/** * Returns the number of instances currently borrowed from this pool. */ intgetNumActive();
/** * Clears any objects sitting idle in the pool。 */ voidclear()throws Exception, UnsupportedOperationException;
/** * Closes this pool, and free any resources associated with it. */ @Override voidclose(); }
Objectobj=null; try { // pre-loading a pool with idle objects. pool.addObject(); // Obtains an instance from this pool. obj = pool.borrowObject(); try { //...use the object... } catch(Exception e) { // invalidate the object pool.invalidateObject(obj); // do not return the object to the pool twice obj = null; } finally { // make sure the object is returned to the pool if(null != obj) { pool.returnObject(obj); } } } catch(Exception e) { // failed to borrow an object }
/** * Create a new proxied object pool. * * @param pool The object pool to wrap * @param proxySource The source of the proxy objects */ publicProxiedObjectPool(final ObjectPool<T> pool, final ProxySource<T> proxySource) { this.pool = pool; this.proxySource = proxySource; }
publicvoidreturnObject(final T obj) { // #1 获取对象对应的池化对象 final PooledObject<T> p = allObjects.get(newIdentityWrapper<>(obj)); if (p == null) { if (!isAbandonedConfig()) { thrownewIllegalStateException("Returned object not currently part of this pool"); } return; // Object was abandoned and removed }
// #4 解除使用 if (!p.deallocate()) { thrownewIllegalStateException( "Object has already been returned to this pool or is invalid"); }
finalintmaxIdleSave= getMaxIdle(); if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) { // #5 池关闭或容量达上限,销毁对象 try { destroy(p); } catch (final Exception e) { swallowException(e); } } else { // #5 进入空闲容器 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(); } } // #6 更新对应状态 updateStatsReturn(activeTime); }
classEvictorimplementsRunnable { /** * 运行对象池维护线程。 * 驱逐对象具有驱逐者的资格,同时保证空闲实例可用的最小数量。 * 因为调用"驱逐者线程"的定时器是被所有对象池共享的, * 但对象池可能存在不同的类加载器中,所以驱逐者必须确保采取的任何行为 * 都得在与对象池相关的工厂的类加载器下。 */ @Override publicvoidrun() { finalClassLoadersavedClassLoader= Thread.currentThread().getContextClassLoader(); try { if (factoryClassLoader != null) { // Set the class loader for the factory // factoryClassLoader 是 classloader 的弱引用 finalClassLoadercl= factoryClassLoader.get(); if (cl == null) { // The pool has been dereferenced and the class loader // GC'd. Cancel this timer so the pool can be GC'd as // well. cancel(); return; } Thread.currentThread().setContextClassLoader(cl); // 见上方中文注释 // [相关的一个 bug](https://issues.apache.org/jira/browse/POOL-161) }
// Evict from the pool try { evict(); } catch(final Exception e) { swallowException(e); } catch(final OutOfMemoryError oome) { // Log problem but give evictor thread a chance to continue // in case error is recoverable oome.printStackTrace(System.err); } // Re-create idle instances. try { ensureMinIdle(); } catch (final Exception e) { swallowException(e); } } finally { // Restore the previous CCL Thread.currentThread().setContextClassLoader(savedClassLoader); } } }
// #4 对所有待检测的"空闲对象"进行驱逐检测 ,注意循环次数,即检测个数是可配置的 for (inti=0, m = getNumTests(); i < m; i++) { // #4.1 初始化"驱逐检测对象(空闲池对象)的迭代器" if (evictionIterator == null || !evictionIterator.hasNext()) { evictionIterator = newEvictionIterator(idleObjects); } if (!evictionIterator.hasNext()) { // Pool exhausted, nothing to do here return; }
try { underTest = evictionIterator.next(); } catch (final NoSuchElementException nsee) { // Object was borrowed in another thread // Don't count this as an eviction test so reduce i; i--; evictionIterator = null; continue; } // #4.2 将"池对象"标记为"开始驱逐状态" if (!underTest.startEvictionTest()) { // Object was borrowed in another thread // Don't count this as an eviction test so reduce i; i--; continue; }
// User provided eviction policy could throw all sorts of // crazy exceptions. Protect against such an exception // killing the eviction thread. boolean evict; try { // #4.3 进行真正的"驱逐检测"操作 evict = evictionPolicy.evict(evictionConfig, underTest, idleObjects.size()); } catch (final Throwable t) { // Slightly convoluted as SwallowedExceptionListener // uses Exception rather than Throwable PoolUtils.checkRethrow(t); swallowException(newException(t)); // Don't evict on error conditions evict = false; }
if (evict) { // #4.3.1 如果"池对象"是可驱逐的,则销毁它 destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } else { // #4.3.2 否则,是否允许空闲时进行有效性测试 if (testWhileIdle) { booleanactive=false; try { // #4.3.2.1 先激活"池对象" factory.activateObject(underTest); active = true; } catch (final Exception e) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } if (active) { if (!factory.validateObject(underTest)) { // #4.3.2.2 如果"池对象"不是有效的,则销毁它 destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } else { try { // #4.3.2.3 否则,钝化并放回池中 factory.passivateObject(underTest); } catch (final Exception e) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } } } } // #4.3.2.4 通知"空闲对象队列",驱逐测试已经结束 if (!underTest.endEvictionTest(idleObjects)) { // TODO - May need to add code here once additional // states are used } } } } } finalAbandonedConfigac=this.abandonedConfig; if (ac != null && ac.getRemoveAbandonedOnMaintenance()) { // #5 移除"被废弃的池对象" removeAbandoned(ac); } }