序本文次要钻研一下jedis的testWhileIdle
testWhileIdleorg/apache/commons/pool2/impl/GenericObjectPool.java
@Override public void evict() throws Exception { assertOpen(); if (!idleObjects.isEmpty()) { PooledObject<T> underTest = null; final EvictionPolicy<T> evictionPolicy = getEvictionPolicy(); synchronized (evictionLock) { final EvictionConfig evictionConfig = new EvictionConfig( getMinEvictableIdleDuration(), getSoftMinEvictableIdleDuration(), getMinIdle()); final boolean 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, DestroyMode.NORMAL); destroyedByEvictorCount.incrementAndGet(); } else { if (testWhileIdle) { boolean active = false; try { factory.activateObject(underTest); active = true; } catch (final Exception e) { destroy(underTest, DestroyMode.NORMAL); destroyedByEvictorCount.incrementAndGet(); } if (active) { boolean validate = false; Throwable validationThrowable = null; try { validate = factory.validateObject(underTest); } catch (final Throwable t) { PoolUtils.checkRethrow(t); validationThrowable = t; } if (!validate) { destroy(underTest, DestroyMode.NORMAL); destroyedByEvictorCount.incrementAndGet(); if (validationThrowable != null) { if (validationThrowable instanceof RuntimeException) { throw (RuntimeException) validationThrowable; } throw (Error) validationThrowable; } } else { try { factory.passivateObject(underTest); } catch (final Exception e) { destroy(underTest, DestroyMode.NORMAL); 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); } }GenericObjectPool的evict办法在idleObjects不为空的时候会执行evict逻辑,它先通过getNumTests获取每次要对多少个idleObject进行验证,之后循环解决,首先通过evictionPolicy.evict判断是否须要evict,如果是则执行destroy办法,否则判断是否testWhileIdle,若是则先执行activateObject办法,再执行validateObject,如果activateObject或者validateObject失败则执行destroy办法,如果validateObject胜利则执行passivateObject办法JedisFactoryredis/clients/jedis/JedisFactory.java
...