if (factory == null) { jmxUnregister(); // tidy up thrownewIllegalArgumentException("factory may not be null"); } this.factory = factory; // 双向阻塞队列 idleObjects = new LinkedBlockingDeque<>(config.getFairness());
publicvoidreturnObject(final T obj) { 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 }
synchronized(p) { final PooledObjectState state = p.getState(); if (state != PooledObjectState.ALLOCATED) { thrownewIllegalStateException( "Object has already been returned to this pool or is invalid"); } p.markReturning(); // Keep from being marked abandoned }
if (!p.deallocate()) { thrownewIllegalStateException( "Object has already been returned to this pool or is invalid"); }
finalint maxIdleSave = getMaxIdle(); if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) { try { destroy(p); } catch (finalException 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); }
PooledObject<T> underTest = null; final EvictionPolicy<T> evictionPolicy = getEvictionPolicy();
synchronized (evictionLock) { final EvictionConfig evictionConfig = new EvictionConfig( getMinEvictableIdleTimeMillis(), getSoftMinEvictableIdleTimeMillis(), getMinIdle());
finalboolean testWhileIdle = getTestWhileIdle();
for (int i = 0, m = getNumTests(); i < m; i++) { if (evictionIterator == null || !evictionIterator.hasNext()) { evictionIterator = new EvictionIterator(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; }
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 { evict = evictionPolicy.evict(evictionConfig, underTest, idleObjects.size()); } catch (final Throwable t) { // Slightly convoluted as SwallowedExceptionListener // uses Exception rather than Throwable PoolUtils.checkRethrow(t); swallowException(new Exception(t)); // Don't evict on error conditions evict = false; }
if (evict) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } else { //定时任务校验对象 if (testWhileIdle) { boolean active = false; try { factory.activateObject(underTest); active = true; } catch (final Exception e) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } if (active) { if (!factory.validateObject(underTest)) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } else { try { factory.passivateObject(underTest); } catch (final Exception e) { destroy(underTest); destroyedByEvictorCount.incrementAndGet(); } } } } if (!underTest.endEvictionTest(idleObjects)) { // TODO - May need to add code here once additional // states are used } } } } } final AbandonedConfig ac = this.abandonedConfig; if (ac != null && ac.getRemoveAbandonedOnMaintenance()) { //同时会清除废弃对象 removeAbandoned(ac); } }