    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.pool2.impl;
    018
    019import java.io.PrintWriter;
    020import java.io.StringWriter;
    021import java.io.Writer;
    022import java.lang.management.ManagementFactory;
    023import java.lang.ref.WeakReference;
    024import java.lang.reflect.InvocationTargetException;
    025import java.util.Arrays;
    026import java.util.Deque;
    027import java.util.Iterator;
    028import java.util.TimerTask;
    029import java.util.concurrent.ScheduledFuture;
    030import java.util.concurrent.TimeUnit;
    031import java.util.concurrent.atomic.AtomicLong;
    032
    033import javax.management.InstanceAlreadyExistsException;
    034import javax.management.InstanceNotFoundException;
    035import javax.management.MBeanRegistrationException;
    036import javax.management.MBeanServer;
    037import javax.management.MalformedObjectNameException;
    038import javax.management.NotCompliantMBeanException;
    039import javax.management.ObjectName;
    040
    041import org.apache.commons.pool2.BaseObject;
    042import org.apache.commons.pool2.PooledObject;
    043import org.apache.commons.pool2.PooledObjectState;
    044import org.apache.commons.pool2.SwallowedExceptionListener;
    045
    046/**
    047 * Base class that provides common functionality for {@link GenericObjectPool}
    048 * and {@link GenericKeyedObjectPool}. The primary reason this class exists is
    049 * reduce code duplication between the two pool implementations.
    050 *
    051 * @param <T> Type of element pooled in this pool.
    052 *
    053 * This class is intended to be thread-safe.
    054 *
    055 * @since 2.0
    056 */
    057public abstract class BaseGenericObjectPool<T> extends BaseObject {
    058
    059    // Constants
    060    /**
    061     * The size of the caches used to store historical data for some attributes
    062     * so that rolling means may be calculated.
    063     */
    064    public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100;
    065
    066    private static final String EVICTION_POLICY_TYPE_NAME = EvictionPolicy.class.getName();
    067
    068    // Configuration attributes
    069    private volatile int maxTotal =
    070            GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
    071    private volatile boolean blockWhenExhausted =
    072            BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
    073    private volatile long maxWaitMillis =
    074            BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
    075    private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
    076    private final boolean fairness;
    077    private volatile boolean testOnCreate =
    078            BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
    079    private volatile boolean testOnBorrow =
    080            BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
    081    private volatile boolean testOnReturn =
    082            BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
    083    private volatile boolean testWhileIdle =
    084            BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
    085    private volatile long timeBetweenEvictionRunsMillis =
    086            BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    087    private volatile int numTestsPerEvictionRun =
    088            BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    089    private volatile long minEvictableIdleTimeMillis =
    090            BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    091    private volatile long softMinEvictableIdleTimeMillis =
    092            BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    093    private volatile EvictionPolicy<T> evictionPolicy;
    094    private volatile long evictorShutdownTimeoutMillis =
    095            BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
    096
    097
    098    // Internal (primarily state) attributes
    099    final Object closeLock = new Object();
    100    volatile boolean closed = false;
    101    final Object evictionLock = new Object();
    102    private Evictor evictor = null; // @GuardedBy("evictionLock")
    103    EvictionIterator evictionIterator = null; // @GuardedBy("evictionLock")
    104    /*
    105     * Class loader for evictor thread to use since, in a JavaEE or similar
    106     * environment, the context class loader for the evictor thread may not have
    107     * visibility of the correct factory. See POOL-161. Uses a weak reference to
    108     * avoid potential memory leaks if the Pool is discarded rather than closed.
    109     */
    110    private final WeakReference<ClassLoader> factoryClassLoader;
    111
    112
    113    // Monitoring (primarily JMX) attributes
    114    private final ObjectName objectName;
    115    private final String creationStackTrace;
    116    private final AtomicLong borrowedCount = new AtomicLong(0);
    117    private final AtomicLong returnedCount = new AtomicLong(0);
    118    final AtomicLong createdCount = new AtomicLong(0);
    119    final AtomicLong destroyedCount = new AtomicLong(0);
    120    final AtomicLong destroyedByEvictorCount = new AtomicLong(0);
    121    final AtomicLong destroyedByBorrowValidationCount = new AtomicLong(0);
    122    private final StatsStore activeTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    123    private final StatsStore idleTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    124    private final StatsStore waitTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    125    private final AtomicLong maxBorrowWaitTimeMillis = new AtomicLong(0L);
    126    private volatile SwallowedExceptionListener swallowedExceptionListener = null;
    127
    128
    129    /**
    130     * Handles JMX registration (if required) and the initialization required for
    131     * monitoring.
    132     *
    133     * @param config        Pool configuration
    134     * @param jmxNameBase   The default base JMX name for the new pool unless
    135     *                      overridden by the config
    136     * @param jmxNamePrefix Prefix to be used for JMX name for the new pool
    137     */
    138    public BaseGenericObjectPool(final BaseObjectPoolConfig<T> config,
    139            final String jmxNameBase, final String jmxNamePrefix) {
    140        if (config.getJmxEnabled()) {
    141            this.objectName = jmxRegister(config, jmxNameBase, jmxNamePrefix);
    142        } else {
    143            this.objectName = null;
    144        }
    145
    146        // Populate the creation stack trace
    147        this.creationStackTrace = getStackTrace(new Exception());
    148
    149        // save the current TCCL (if any) to be used later by the evictor Thread
    150        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
    151        if (cl == null) {
    152            factoryClassLoader = null;
    153        } else {
    154            factoryClassLoader = new WeakReference<>(cl);
    155        }
    156
    157        fairness = config.getFairness();
    158    }
    159
    160
    161    /**
    162     * Returns the maximum number of objects that can be allocated by the pool
    163     * (checked out to clients, or idle awaiting checkout) at a given time. When
    164     * negative, there is no limit to the number of objects that can be
    165     * managed by the pool at one time.
    166     *
    167     * @return the cap on the total number of object instances managed by the
    168     *         pool.
    169     *
    170     * @see #setMaxTotal
    171     */
    172    public final int getMaxTotal() {
    173        return maxTotal;
    174    }
    175
    176    /**
    177     * Sets the cap on the number of objects that can be allocated by the pool
    178     * (checked out to clients, or idle awaiting checkout) at a given time. Use
    179     * a negative value for no limit.
    180     *
    181     * @param maxTotal  The cap on the total number of object instances managed
    182     *                  by the pool. Negative values mean that there is no limit
    183     *                  to the number of objects allocated by the pool.
    184     *
    185     * @see #getMaxTotal
    186     */
    187    public final void setMaxTotal(final int maxTotal) {
    188        this.maxTotal = maxTotal;
    189    }
    190
    191    /**
    192     * Returns whether to block when the <code>borrowObject()</code> method is
    193     * invoked when the pool is exhausted (the maximum number of "active"
    194     * objects has been reached).
    195     *
    196     * @return <code>true</code> if <code>borrowObject()</code> should block
    197     *         when the pool is exhausted
    198     *
    199     * @see #setBlockWhenExhausted
    200     */
    201    public final boolean getBlockWhenExhausted() {
    202        return blockWhenExhausted;
    203    }
    204
    205    /**
    206     * Sets whether to block when the <code>borrowObject()</code> method is
    207     * invoked when the pool is exhausted (the maximum number of "active"
    208     * objects has been reached).
    209     *
    210     * @param blockWhenExhausted    <code>true</code> if
    211     *                              <code>borrowObject()</code> should block
    212     *                              when the pool is exhausted
    213     *
    214     * @see #getBlockWhenExhausted
    215     */
    216    public final void setBlockWhenExhausted(final boolean blockWhenExhausted) {
    217        this.blockWhenExhausted = blockWhenExhausted;
    218    }
    219
    220    protected void setConfig(final BaseObjectPoolConfig<T> conf) {
    221        setLifo(conf.getLifo());
    222        setMaxWaitMillis(conf.getMaxWaitMillis());
    223        setBlockWhenExhausted(conf.getBlockWhenExhausted());
    224        setTestOnCreate(conf.getTestOnCreate());
    225        setTestOnBorrow(conf.getTestOnBorrow());
    226        setTestOnReturn(conf.getTestOnReturn());
    227        setTestWhileIdle(conf.getTestWhileIdle());
    228        setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
    229        setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
    230        setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
    231        setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
    232        final EvictionPolicy<T> policy = conf.getEvictionPolicy();
    233        if (policy == null) {
    234            // Use the class name (pre-2.6.0 compatible)
    235            setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
    236        } else {
    237            // Otherwise, use the class (2.6.0 feature)
    238            setEvictionPolicy(policy);
    239        }
    240        setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
    241    }
    242
    243    /**
    244     * Returns the maximum amount of time (in milliseconds) the
    245     * <code>borrowObject()</code> method should block before throwing an
    246     * exception when the pool is exhausted and
    247     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    248     * <code>borrowObject()</code> method may block indefinitely.
    249     *
    250     * @return the maximum number of milliseconds <code>borrowObject()</code>
    251     *         will block.
    252     *
    253     * @see #setMaxWaitMillis
    254     * @see #setBlockWhenExhausted
    255     */
    256    public final long getMaxWaitMillis() {
    257        return maxWaitMillis;
    258    }
    259
    260    /**
    261     * Sets the maximum amount of time (in milliseconds) the
    262     * <code>borrowObject()</code> method should block before throwing an
    263     * exception when the pool is exhausted and
    264     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    265     * <code>borrowObject()</code> method may block indefinitely.
    266     *
    267     * @param maxWaitMillis the maximum number of milliseconds
    268     *                      <code>borrowObject()</code> will block or negative
    269     *                      for indefinitely.
    270     *
    271     * @see #getMaxWaitMillis
    272     * @see #setBlockWhenExhausted
    273     */
    274    public final void setMaxWaitMillis(final long maxWaitMillis) {
    275        this.maxWaitMillis = maxWaitMillis;
    276    }
    277
    278    /**
    279     * Returns whether the pool has LIFO (last in, first out) behaviour with
    280     * respect to idle objects - always returning the most recently used object
    281     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    282     * always returns the oldest object in the idle object pool.
    283     *
    284     * @return <code>true</code> if the pool is configured with LIFO behaviour
    285     *         or <code>false</code> if the pool is configured with FIFO
    286     *         behaviour
    287     *
    288     * @see #setLifo
    289     */
    290    public final boolean getLifo() {
    291        return lifo;
    292    }
    293
    294    /**
    295     * Returns whether or not the pool serves threads waiting to borrow objects fairly.
    296     * True means that waiting threads are served as if waiting in a FIFO queue.
    297     *
    298     * @return <code>true</code> if waiting threads are to be served
    299     *             by the pool in arrival order
    300     */
    301    public final boolean getFairness() {
    302        return fairness;
    303    }
    304
    305    /**
    306     * Sets whether the pool has LIFO (last in, first out) behaviour with
    307     * respect to idle objects - always returning the most recently used object
    308     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    309     * always returns the oldest object in the idle object pool.
    310     *
    311     * @param lifo  <code>true</code> if the pool is to be configured with LIFO
    312     *              behaviour or <code>false</code> if the pool is to be
    313     *              configured with FIFO behaviour
    314     *
    315     * @see #getLifo()
    316     */
    317    public final void setLifo(final boolean lifo) {
    318        this.lifo = lifo;
    319    }
    320
    321    /**
    322     * Returns whether objects created for the pool will be validated before
    323     * being returned from the <code>borrowObject()</code> method. Validation is
    324     * performed by the <code>validateObject()</code> method of the factory
    325     * associated with the pool. If the object fails to validate, then
    326     * <code>borrowObject()</code> will fail.
    327     *
    328     * @return <code>true</code> if newly created objects are validated before
    329     *         being returned from the <code>borrowObject()</code> method
    330     *
    331     * @see #setTestOnCreate
    332     *
    333     * @since 2.2
    334     */
    335    public final boolean getTestOnCreate() {
    336        return testOnCreate;
    337    }
    338
    339    /**
    340     * Sets whether objects created for the pool will be validated before
    341     * being returned from the <code>borrowObject()</code> method. Validation is
    342     * performed by the <code>validateObject()</code> method of the factory
    343     * associated with the pool. If the object fails to validate, then
    344     * <code>borrowObject()</code> will fail.
    345     *
    346     * @param testOnCreate  <code>true</code> if newly created objects should be
    347     *                      validated before being returned from the
    348     *                      <code>borrowObject()</code> method
    349     *
    350     * @see #getTestOnCreate
    351     *
    352     * @since 2.2
    353     */
    354    public final void setTestOnCreate(final boolean testOnCreate) {
    355        this.testOnCreate = testOnCreate;
    356    }
    357
    358    /**
    359     * Returns whether objects borrowed from the pool will be validated before
    360     * being returned from the <code>borrowObject()</code> method. Validation is
    361     * performed by the <code>validateObject()</code> method of the factory
    362     * associated with the pool. If the object fails to validate, it will be
    363     * removed from the pool and destroyed, and a new attempt will be made to
    364     * borrow an object from the pool.
    365     *
    366     * @return <code>true</code> if objects are validated before being returned
    367     *         from the <code>borrowObject()</code> method
    368     *
    369     * @see #setTestOnBorrow
    370     */
    371    public final boolean getTestOnBorrow() {
    372        return testOnBorrow;
    373    }
    374
    375    /**
    376     * Sets whether objects borrowed from the pool will be validated before
    377     * being returned from the <code>borrowObject()</code> method. Validation is
    378     * performed by the <code>validateObject()</code> method of the factory
    379     * associated with the pool. If the object fails to validate, it will be
    380     * removed from the pool and destroyed, and a new attempt will be made to
    381     * borrow an object from the pool.
    382     *
    383     * @param testOnBorrow  <code>true</code> if objects should be validated
    384     *                      before being returned from the
    385     *                      <code>borrowObject()</code> method
    386     *
    387     * @see #getTestOnBorrow
    388     */
    389    public final void setTestOnBorrow(final boolean testOnBorrow) {
    390        this.testOnBorrow = testOnBorrow;
    391    }
    392
    393    /**
    394     * Returns whether objects borrowed from the pool will be validated when
    395     * they are returned to the pool via the <code>returnObject()</code> method.
    396     * Validation is performed by the <code>validateObject()</code> method of
    397     * the factory associated with the pool. Returning objects that fail validation
    398     * are destroyed rather then being returned the pool.
    399     *
    400     * @return <code>true</code> if objects are validated on return to
    401     *         the pool via the <code>returnObject()</code> method
    402     *
    403     * @see #setTestOnReturn
    404     */
    405    public final boolean getTestOnReturn() {
    406        return testOnReturn;
    407    }
    408
    409    /**
    410     * Sets whether objects borrowed from the pool will be validated when
    411     * they are returned to the pool via the <code>returnObject()</code> method.
    412     * Validation is performed by the <code>validateObject()</code> method of
    413     * the factory associated with the pool. Returning objects that fail validation
    414     * are destroyed rather then being returned the pool.
    415     *
    416     * @param testOnReturn <code>true</code> if objects are validated on
    417     *                     return to the pool via the
    418     *                     <code>returnObject()</code> method
    419     *
    420     * @see #getTestOnReturn
    421     */
    422    public final void setTestOnReturn(final boolean testOnReturn) {
    423        this.testOnReturn = testOnReturn;
    424    }
    425
    426    /**
    427     * Returns whether objects sitting idle in the pool will be validated by the
    428     * idle object evictor (if any - see
    429     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    430     * by the <code>validateObject()</code> method of the factory associated
    431     * with the pool. If the object fails to validate, it will be removed from
    432     * the pool and destroyed.
    433     *
    434     * @return <code>true</code> if objects will be validated by the evictor
    435     *
    436     * @see #setTestWhileIdle
    437     * @see #setTimeBetweenEvictionRunsMillis
    438     */
    439    public final boolean getTestWhileIdle() {
    440        return testWhileIdle;
    441    }
    442
    443    /**
    444     * Returns whether objects sitting idle in the pool will be validated by the
    445     * idle object evictor (if any - see
    446     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    447     * by the <code>validateObject()</code> method of the factory associated
    448     * with the pool. If the object fails to validate, it will be removed from
    449     * the pool and destroyed.  Note that setting this property has no effect
    450     * unless the idle object evictor is enabled by setting
    451     * <code>timeBetweenEvictionRunsMillis</code> to a positive value.
    452     *
    453     * @param testWhileIdle
    454     *            <code>true</code> so objects will be validated by the evictor
    455     *
    456     * @see #getTestWhileIdle
    457     * @see #setTimeBetweenEvictionRunsMillis
    458     */
    459    public final void setTestWhileIdle(final boolean testWhileIdle) {
    460        this.testWhileIdle = testWhileIdle;
    461    }
    462
    463    /**
    464     * Returns the number of milliseconds to sleep between runs of the idle
    465     * object evictor thread. When non-positive, no idle object evictor thread
    466     * will be run.
    467     *
    468     * @return number of milliseconds to sleep between evictor runs
    469     *
    470     * @see #setTimeBetweenEvictionRunsMillis
    471     */
    472    public final long getTimeBetweenEvictionRunsMillis() {
    473        return timeBetweenEvictionRunsMillis;
    474    }
    475
    476    /**
    477     * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
    478     * <ul>
    479     * <li>When positive, the idle object evictor thread starts.</li>
    480     * <li>When non-positive, no idle object evictor thread runs.</li>
    481     * </ul>
    482     *
    483     * @param timeBetweenEvictionRunsMillis
    484     *            number of milliseconds to sleep between evictor runs
    485     *
    486     * @see #getTimeBetweenEvictionRunsMillis
    487     */
    488    public final void setTimeBetweenEvictionRunsMillis(
    489            final long timeBetweenEvictionRunsMillis) {
    490        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    491        startEvictor(timeBetweenEvictionRunsMillis);
    492    }
    493
    494    /**
    495     * Returns the maximum number of objects to examine during each run (if any)
    496     * of the idle object evictor thread. When positive, the number of tests
    497     * performed for a run will be the minimum of the configured value and the
    498     * number of idle instances in the pool. When negative, the number of tests
    499     * performed will be <code>ceil({@link #getNumIdle}/
    500     * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
    501     * value is <code>-n</code> roughly one nth of the idle objects will be
    502     * tested per run.
    503     *
    504     * @return max number of objects to examine during each evictor run
    505     *
    506     * @see #setNumTestsPerEvictionRun
    507     * @see #setTimeBetweenEvictionRunsMillis
    508     */
    509    public final int getNumTestsPerEvictionRun() {
    510        return numTestsPerEvictionRun;
    511    }
    512
    513    /**
    514     * Sets the maximum number of objects to examine during each run (if any)
    515     * of the idle object evictor thread. When positive, the number of tests
    516     * performed for a run will be the minimum of the configured value and the
    517     * number of idle instances in the pool. When negative, the number of tests
    518     * performed will be <code>ceil({@link #getNumIdle}/
    519     * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
    520     * value is <code>-n</code> roughly one nth of the idle objects will be
    521     * tested per run.
    522     *
    523     * @param numTestsPerEvictionRun
    524     *            max number of objects to examine during each evictor run
    525     *
    526     * @see #getNumTestsPerEvictionRun
    527     * @see #setTimeBetweenEvictionRunsMillis
    528     */
    529    public final void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
    530        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    531    }
    532
    533    /**
    534     * Returns the minimum amount of time an object may sit idle in the pool
    535     * before it is eligible for eviction by the idle object evictor (if any -
    536     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    537     * no objects will be evicted from the pool due to idle time alone.
    538     *
    539     * @return minimum amount of time an object may sit idle in the pool before
    540     *         it is eligible for eviction
    541     *
    542     * @see #setMinEvictableIdleTimeMillis
    543     * @see #setTimeBetweenEvictionRunsMillis
    544     */
    545    public final long getMinEvictableIdleTimeMillis() {
    546        return minEvictableIdleTimeMillis;
    547    }
    548
    549    /**
    550     * Sets the minimum amount of time an object may sit idle in the pool
    551     * before it is eligible for eviction by the idle object evictor (if any -
    552     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    553     * no objects will be evicted from the pool due to idle time alone.
    554     *
    555     * @param minEvictableIdleTimeMillis
    556     *            minimum amount of time an object may sit idle in the pool
    557     *            before it is eligible for eviction
    558     *
    559     * @see #getMinEvictableIdleTimeMillis
    560     * @see #setTimeBetweenEvictionRunsMillis
    561     */
    562    public final void setMinEvictableIdleTimeMillis(
    563            final long minEvictableIdleTimeMillis) {
    564        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    565    }
    566
    567    /**
    568     * Returns the minimum amount of time an object may sit idle in the pool
    569     * before it is eligible for eviction by the idle object evictor (if any -
    570     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    571     * with the extra condition that at least <code>minIdle</code> object
    572     * instances remain in the pool. This setting is overridden by
    573     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    574     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    575     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    576     *
    577     * @return minimum amount of time an object may sit idle in the pool before
    578     *         it is eligible for eviction if minIdle instances are available
    579     *
    580     * @see #setSoftMinEvictableIdleTimeMillis
    581     */
    582    public final long getSoftMinEvictableIdleTimeMillis() {
    583        return softMinEvictableIdleTimeMillis;
    584    }
    585
    586    /**
    587     * Sets the minimum amount of time an object may sit idle in the pool
    588     * before it is eligible for eviction by the idle object evictor (if any -
    589     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    590     * with the extra condition that at least <code>minIdle</code> object
    591     * instances remain in the pool. This setting is overridden by
    592     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    593     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    594     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    595     *
    596     * @param softMinEvictableIdleTimeMillis
    597     *            minimum amount of time an object may sit idle in the pool
    598     *            before it is eligible for eviction if minIdle instances are
    599     *            available
    600     *
    601     * @see #getSoftMinEvictableIdleTimeMillis
    602     */
    603    public final void setSoftMinEvictableIdleTimeMillis(
    604            final long softMinEvictableIdleTimeMillis) {
    605        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
    606    }
    607
    608    /**
    609     * Returns the name of the {@link EvictionPolicy} implementation that is
    610     * used by this pool.
    611     *
    612     * @return  The fully qualified class name of the {@link EvictionPolicy}
    613     *
    614     * @see #setEvictionPolicyClassName(String)
    615     */
    616    public final String getEvictionPolicyClassName() {
    617        return evictionPolicy.getClass().getName();
    618    }
    619
    620    /**
    621     * Sets the eviction policy for this pool.
    622     *
    623     * @param evictionPolicy
    624     *            the eviction policy for this pool.
    625     * @since 2.6.0
    626     */
    627    public void setEvictionPolicy(final EvictionPolicy<T> evictionPolicy) {
    628        this.evictionPolicy = evictionPolicy;
    629    }
    630
    631    /**
    632     * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
    633     * load the class using the given class loader. If that fails, use the class loader for the {@link EvictionPolicy}
    634     * interface.
    635     *
    636     * @param evictionPolicyClassName
    637     *            the fully qualified class name of the new eviction policy
    638     * @param classLoader
    639     *            the class loader to load the given {@code evictionPolicyClassName}.
    640     *
    641     * @see #getEvictionPolicyClassName()
    642     * @since 2.6.0 If loading the class using the given class loader fails, use the class loader for the
    643     *        {@link EvictionPolicy} interface.
    644     */
    645    public final void setEvictionPolicyClassName(final String evictionPolicyClassName, final ClassLoader classLoader) {
    646        // Getting epClass here and now best matches the caller's environment
    647        final Class<?> epClass = EvictionPolicy.class;
    648        final ClassLoader epClassLoader = epClass.getClassLoader();
    649        try {
    650            try {
    651                setEvictionPolicy(evictionPolicyClassName, classLoader);
    652            } catch (final ClassCastException | ClassNotFoundException e) {
    653                setEvictionPolicy(evictionPolicyClassName, epClassLoader);
    654            }
    655        } catch (final ClassCastException e) {
    656            throw new IllegalArgumentException("Class " + evictionPolicyClassName + " from class loaders ["
    657                    + classLoader + ", " + epClassLoader + "] do not implement " + EVICTION_POLICY_TYPE_NAME);
    658        } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException
    659                | InvocationTargetException | NoSuchMethodException e) {
    660            final String exMessage = "Unable to create " + EVICTION_POLICY_TYPE_NAME + " instance of type "
    661                    + evictionPolicyClassName;
    662            throw new IllegalArgumentException(exMessage, e);
    663        }
    664    }
    665
    666    @SuppressWarnings("unchecked")
    667    private void setEvictionPolicy(final String className, final ClassLoader classLoader)
    668            throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    669        final Class<?> clazz = Class.forName(className, true, classLoader);
    670        final Object policy = clazz.getConstructor().newInstance();
    671        this.evictionPolicy = (EvictionPolicy<T>) policy;
    672    }
    673
    674    /**
    675     * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
    676     * load the class using the thread context class loader. If that fails, the use the class loader for the
    677     * {@link EvictionPolicy} interface.
    678     *
    679     * @param evictionPolicyClassName
    680     *            the fully qualified class name of the new eviction policy
    681     *
    682     * @see #getEvictionPolicyClassName()
    683     * @since 2.6.0 If loading the class using the thread context class loader fails, use the class loader for the
    684     *        {@link EvictionPolicy} interface.
    685     */
    686    public final void setEvictionPolicyClassName(final String evictionPolicyClassName) {
    687        setEvictionPolicyClassName(evictionPolicyClassName, Thread.currentThread().getContextClassLoader());
    688    }
    689
    690    /**
    691     * Gets the timeout that will be used when waiting for the Evictor to
    692     * shutdown if this pool is closed and it is the only pool still using the
    693     * the value for the Evictor.
    694     *
    695     * @return  The timeout in milliseconds that will be used while waiting for
    696     *          the Evictor to shut down.
    697     */
    698    public final long getEvictorShutdownTimeoutMillis() {
    699        return evictorShutdownTimeoutMillis;
    700    }
    701
    702    /**
    703     * Sets the timeout that will be used when waiting for the Evictor to
    704     * shutdown if this pool is closed and it is the only pool still using the
    705     * the value for the Evictor.
    706     *
    707     * @param evictorShutdownTimeoutMillis  the timeout in milliseconds that
    708     *                                      will be used while waiting for the
    709     *                                      Evictor to shut down.
    710     */
    711    public final void setEvictorShutdownTimeoutMillis(
    712            final long evictorShutdownTimeoutMillis) {
    713        this.evictorShutdownTimeoutMillis = evictorShutdownTimeoutMillis;
    714    }
    715
    716    /**
    717     * Closes the pool, destroys the remaining idle objects and, if registered
    718     * in JMX, deregisters it.
    719     */
    720    public abstract void close();
    721
    722    /**
    723     * Has this pool instance been closed.
    724     * @return <code>true</code> when this pool has been closed.
    725     */
    726    public final boolean isClosed() {
    727        return closed;
    728    }
    729
    730    /**
    731     * <p>Perform <code>numTests</code> idle object eviction tests, evicting
    732     * examined objects that meet the criteria for eviction. If
    733     * <code>testWhileIdle</code> is true, examined objects are validated
    734     * when visited (and removed if invalid); otherwise only objects that
    735     * have been idle for more than <code>minEvicableIdleTimeMillis</code>
    736     * are removed.</p>
    737     *
    738     * @throws Exception when there is a problem evicting idle objects.
    739     */
    740    public abstract void evict() throws Exception;
    741
    742    /**
    743     * Returns the {@link EvictionPolicy} defined for this pool.
    744     *
    745     * @return the eviction policy
    746     * @since 2.4
    747     * @since 2.6.0 Changed access from protected to public.
    748     */
    749    public EvictionPolicy<T> getEvictionPolicy() {
    750        return evictionPolicy;
    751    }
    752
    753    /**
    754     * Verifies that the pool is open.
    755     * @throws IllegalStateException if the pool is closed.
    756     */
    757    final void assertOpen() throws IllegalStateException {
    758        if (isClosed()) {
    759            throw new IllegalStateException("Pool not open");
    760        }
    761    }
    762
    763    /**
    764     * <p>Starts the evictor with the given delay. If there is an evictor
    765     * running when this method is called, it is stopped and replaced with a
    766     * new evictor with the specified delay.</p>
    767     *
    768     * <p>This method needs to be final, since it is called from a constructor.
    769     * See POOL-195.</p>
    770     *
    771     * @param delay time in milliseconds before start and between eviction runs
    772     */
    773    final void startEvictor(final long delay) {
    774        synchronized (evictionLock) {
    775            EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS);
    776            evictor = null;
    777            evictionIterator = null;
    778            if (delay > 0) {
    779                evictor = new Evictor();
    780                EvictionTimer.schedule(evictor, delay, delay);
    781            }
    782        }
    783    }
    784
    785    /**
    786     * Stops the evictor.
    787     */
    788    void stopEvitor() {
    789        startEvictor(-1L);
    790    }
    791    /**
    792     * Tries to ensure that the configured minimum number of idle instances are
    793     * available in the pool.
    794     * @throws Exception if an error occurs creating idle instances
    795     */
    796    abstract void ensureMinIdle() throws Exception;
    797
    798
    799    // Monitoring (primarily JMX) related methods
    800
    801    /**
    802     * Provides the name under which the pool has been registered with the
    803     * platform MBean server or <code>null</code> if the pool has not been
    804     * registered.
    805     * @return the JMX name
    806     */
    807    public final ObjectName getJmxName() {
    808        return objectName;
    809    }
    810
    811    /**
    812     * Provides the stack trace for the call that created this pool. JMX
    813     * registration may trigger a memory leak so it is important that pools are
    814     * deregistered when no longer used by calling the {@link #close()} method.
    815     * This method is provided to assist with identifying code that creates but
    816     * does not close it thereby creating a memory leak.
    817     * @return pool creation stack trace
    818     */
    819    public final String getCreationStackTrace() {
    820        return creationStackTrace;
    821    }
    822
    823    /**
    824     * The total number of objects successfully borrowed from this pool over the
    825     * lifetime of the pool.
    826     * @return the borrowed object count
    827     */
    828    public final long getBorrowedCount() {
    829        return borrowedCount.get();
    830    }
    831
    832    /**
    833     * The total number of objects returned to this pool over the lifetime of
    834     * the pool. This excludes attempts to return the same object multiple
    835     * times.
    836     * @return the returned object count
    837     */
    838    public final long getReturnedCount() {
    839        return returnedCount.get();
    840    }
    841
    842    /**
    843     * The total number of objects created for this pool over the lifetime of
    844     * the pool.
    845     * @return the created object count
    846     */
    847    public final long getCreatedCount() {
    848        return createdCount.get();
    849    }
    850
    851    /**
    852     * The total number of objects destroyed by this pool over the lifetime of
    853     * the pool.
    854     * @return the destroyed object count
    855     */
    856    public final long getDestroyedCount() {
    857        return destroyedCount.get();
    858    }
    859
    860    /**
    861     * The total number of objects destroyed by the evictor associated with this
    862     * pool over the lifetime of the pool.
    863     * @return the evictor destroyed object count
    864     */
    865    public final long getDestroyedByEvictorCount() {
    866        return destroyedByEvictorCount.get();
    867    }
    868
    869    /**
    870     * The total number of objects destroyed by this pool as a result of failing
    871     * validation during <code>borrowObject()</code> over the lifetime of the
    872     * pool.
    873     * @return validation destroyed object count
    874     */
    875    public final long getDestroyedByBorrowValidationCount() {
    876        return destroyedByBorrowValidationCount.get();
    877    }
    878
    879    /**
    880     * The mean time objects are active for based on the last {@link
    881     * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
    882     * @return mean time an object has been checked out from the pool among
    883     * recently returned objects
    884     */
    885    public final long getMeanActiveTimeMillis() {
    886        return activeTimes.getMean();
    887    }
    888
    889    /**
    890     * The mean time objects are idle for based on the last {@link
    891     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    892     * @return mean time an object has been idle in the pool among recently
    893     * borrowed objects
    894     */
    895    public final long getMeanIdleTimeMillis() {
    896        return idleTimes.getMean();
    897    }
    898
    899    /**
    900     * The mean time threads wait to borrow an object based on the last {@link
    901     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    902     * @return mean time in milliseconds that a recently served thread has had
    903     * to wait to borrow an object from the pool
    904     */
    905    public final long getMeanBorrowWaitTimeMillis() {
    906        return waitTimes.getMean();
    907    }
    908
    909    /**
    910     * The maximum time a thread has waited to borrow objects from the pool.
    911     * @return maximum wait time in milliseconds since the pool was created
    912     */
    913    public final long getMaxBorrowWaitTimeMillis() {
    914        return maxBorrowWaitTimeMillis.get();
    915    }
    916
    917    /**
    918     * The number of instances currently idle in this pool.
    919     * @return count of instances available for checkout from the pool
    920     */
    921    public abstract int getNumIdle();
    922
    923    /**
    924     * The listener used (if any) to receive notifications of exceptions
    925     * unavoidably swallowed by the pool.
    926     *
    927     * @return The listener or <code>null</code> for no listener
    928     */
    929    public final SwallowedExceptionListener getSwallowedExceptionListener() {
    930        return swallowedExceptionListener;
    931    }
    932
    933    /**
    934     * The listener used (if any) to receive notifications of exceptions
    935     * unavoidably swallowed by the pool.
    936     *
    937     * @param swallowedExceptionListener    The listener or <code>null</code>
    938     *                                      for no listener
    939     */
    940    public final void setSwallowedExceptionListener(
    941            final SwallowedExceptionListener swallowedExceptionListener) {
    942        this.swallowedExceptionListener = swallowedExceptionListener;
    943    }
    944
    945    /**
    946     * Swallows an exception and notifies the configured listener for swallowed
    947     * exceptions queue.
    948     *
    949     * @param swallowException exception to be swallowed
    950     */
    951    final void swallowException(final Exception swallowException) {
    952        final SwallowedExceptionListener listener = getSwallowedExceptionListener();
    953
    954        if (listener == null) {
    955            return;
    956        }
    957
    958        try {
    959            listener.onSwallowException(swallowException);
    960        } catch (final VirtualMachineError e) {
    961            throw e;
    962        } catch (final Throwable t) {
    963            // Ignore. Enjoy the irony.
    964        }
    965    }
    966
    967    /**
    968     * Updates statistics after an object is borrowed from the pool.
    969     * @param p object borrowed from the pool
    970     * @param waitTime time (in milliseconds) that the borrowing thread had to wait
    971     */
    972    final void updateStatsBorrow(final PooledObject<T> p, final long waitTime) {
    973        borrowedCount.incrementAndGet();
    974        idleTimes.add(p.getIdleTimeMillis());
    975        waitTimes.add(waitTime);
    976
    977        // lock-free optimistic-locking maximum
    978        long currentMax;
    979        do {
    980            currentMax = maxBorrowWaitTimeMillis.get();
    981            if (currentMax >= waitTime) {
    982                break;
    983            }
    984        } while (!maxBorrowWaitTimeMillis.compareAndSet(currentMax, waitTime));
    985    }
    986
    987    /**
    988     * Updates statistics after an object is returned to the pool.
    989     * @param activeTime the amount of time (in milliseconds) that the returning
    990     * object was checked out
    991     */
    992    final void updateStatsReturn(final long activeTime) {
    993        returnedCount.incrementAndGet();
    994        activeTimes.add(activeTime);
    995    }
    996
    997    /**
    998     * Marks the object as returning to the pool.
    999     * @param pooledObject instance to return to the keyed pool
    1000     */
    1001    protected void markReturningState(final PooledObject<T> pooledObject) {
    1002        synchronized(pooledObject) {
    1003            final PooledObjectState state = pooledObject.getState();
    1004            if (state != PooledObjectState.ALLOCATED) {
    1005                throw new IllegalStateException(
    1006                        "Object has already been returned to this pool or is invalid");
    1007            }
    1008            pooledObject.markReturning(); // Keep from being marked abandoned
    1009        }
    1010    }
    1011
    1012    /**
    1013     * Unregisters this pool's MBean.
    1014     */
    1015    final void jmxUnregister() {
    1016        if (objectName != null) {
    1017            try {
    1018                ManagementFactory.getPlatformMBeanServer().unregisterMBean(
    1019                        objectName);
    1020            } catch (final MBeanRegistrationException | InstanceNotFoundException e) {
    1021                swallowException(e);
    1022            }
    1023        }
    1024    }
    1025
    1026    /**
    1027     * Registers the pool with the platform MBean server.
    1028     * The registered name will be
    1029     * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least
    1030     * integer greater than or equal to 1 such that the name is not already
    1031     * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
    1032     * returning null.
    1033     *
    1034     * @param config Pool configuration
    1035     * @param jmxNameBase default base JMX name for this pool
    1036     * @param jmxNamePrefix name prefix
    1037     * @return registered ObjectName, null if registration fails
    1038     */
    1039    private ObjectName jmxRegister(final BaseObjectPoolConfig<T> config,
    1040            final String jmxNameBase, String jmxNamePrefix) {
    1041        ObjectName newObjectName = null;
    1042        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    1043        int i = 1;
    1044        boolean registered = false;
    1045        String base = config.getJmxNameBase();
    1046        if (base == null) {
    1047            base = jmxNameBase;
    1048        }
    1049        while (!registered) {
    1050            try {
    1051                ObjectName objName;
    1052                // Skip the numeric suffix for the first pool in case there is
    1053                // only one so the names are cleaner.
    1054                if (i == 1) {
    1055                    objName = new ObjectName(base + jmxNamePrefix);
    1056                } else {
    1057                    objName = new ObjectName(base + jmxNamePrefix + i);
    1058                }
    1059                mbs.registerMBean(this, objName);
    1060                newObjectName = objName;
    1061                registered = true;
    1062            } catch (final MalformedObjectNameException e) {
    1063                if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals(
    1064                        jmxNamePrefix) && jmxNameBase.equals(base)) {
    1065                    // Shouldn't happen. Skip registration if it does.
    1066                    registered = true;
    1067                } else {
    1068                    // Must be an invalid name. Use the defaults instead.
    1069                    jmxNamePrefix =
    1070                            BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX;
    1071                    base = jmxNameBase;
    1072                }
    1073            } catch (final InstanceAlreadyExistsException e) {
    1074                // Increment the index and try again
    1075                i++;
    1076            } catch (final MBeanRegistrationException | NotCompliantMBeanException e) {
    1077                // Shouldn't happen. Skip registration if it does.
    1078                registered = true;
    1079            }
    1080        }
    1081        return newObjectName;
    1082    }
    1083
    1084    /**
    1085     * Gets the stack trace of an exception as a string.
    1086     * @param e exception to trace
    1087     * @return exception stack trace as a string
    1088     */
    1089    private String getStackTrace(final Exception e) {
    1090        // Need the exception in string form to prevent the retention of
    1091        // references to classes in the stack trace that could trigger a memory
    1092        // leak in a container environment.
    1093        final Writer w = new StringWriter();
    1094        final PrintWriter pw = new PrintWriter(w);
    1095        e.printStackTrace(pw);
    1096        return w.toString();
    1097    }
    1098
    1099    // Inner classes
    1100
    1101    /**
    1102     * The idle object evictor {@link TimerTask}.
    1103     *
    1104     * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
    1105     */
    1106    class Evictor implements Runnable {
    1107
    1108        private ScheduledFuture<?> scheduledFuture;
    1109
    1110        /**
    1111         * Run pool maintenance.  Evict objects qualifying for eviction and then
    1112         * ensure that the minimum number of idle instances are available.
    1113         * Since the Timer that invokes Evictors is shared for all Pools but
    1114         * pools may exist in different class loaders, the Evictor ensures that
    1115         * any actions taken are under the class loader of the factory
    1116         * associated with the pool.
    1117         */
    1118        @Override
    1119        public void run() {
    1120            final ClassLoader savedClassLoader =
    1121                    Thread.currentThread().getContextClassLoader();
    1122            try {
    1123                if (factoryClassLoader != null) {
    1124                    // Set the class loader for the factory
    1125                    final ClassLoader cl = factoryClassLoader.get();
    1126                    if (cl == null) {
    1127                        // The pool has been dereferenced and the class loader
    1128                        // GC'd. Cancel this timer so the pool can be GC'd as
    1129                        // well.
    1130                        cancel();
    1131                        return;
    1132                    }
    1133                    Thread.currentThread().setContextClassLoader(cl);
    1134                }
    1135
    1136                // Evict from the pool
    1137                try {
    1138                    evict();
    1139                } catch(final Exception e) {
    1140                    swallowException(e);
    1141                } catch(final OutOfMemoryError oome) {
    1142                    // Log problem but give evictor thread a chance to continue
    1143                    // in case error is recoverable
    1144                    oome.printStackTrace(System.err);
    1145                }
    1146                // Re-create idle instances.
    1147                try {
    1148                    ensureMinIdle();
    1149                } catch (final Exception e) {
    1150                    swallowException(e);
    1151                }
    1152            } finally {
    1153                // Restore the previous CCL
    1154                Thread.currentThread().setContextClassLoader(savedClassLoader);
    1155            }
    1156        }
    1157
    1158
    1159        void setScheduledFuture(final ScheduledFuture<?> scheduledFuture) {
    1160            this.scheduledFuture = scheduledFuture;
    1161        }
    1162
    1163
    1164        void cancel() {
    1165            scheduledFuture.cancel(false);
    1166        }
    1167    }
    1168
    1169    /**
    1170     * Maintains a cache of values for a single metric and reports
    1171     * statistics on the cached values.
    1172     */
    1173    private class StatsStore {
    1174
    1175        private final AtomicLong values[];
    1176        private final int size;
    1177        private int index;
    1178
    1179        /**
    1180         * Create a StatsStore with the given cache size.
    1181         *
    1182         * @param size number of values to maintain in the cache.
    1183         */
    1184        public StatsStore(final int size) {
    1185            this.size = size;
    1186            values = new AtomicLong[size];
    1187            for (int i = 0; i < size; i++) {
    1188                values[i] = new AtomicLong(-1);
    1189            }
    1190        }
    1191
    1192        /**
    1193         * Adds a value to the cache.  If the cache is full, one of the
    1194         * existing values is replaced by the new value.
    1195         *
    1196         * @param value new value to add to the cache.
    1197         */
    1198        public synchronized void add(final long value) {
    1199            values[index].set(value);
    1200            index++;
    1201            if (index == size) {
    1202                index = 0;
    1203            }
    1204        }
    1205
    1206        /**
    1207         * Returns the mean of the cached values.
    1208         *
    1209         * @return the mean of the cache, truncated to long
    1210         */
    1211        public long getMean() {
    1212            double result = 0;
    1213            int counter = 0;
    1214            for (int i = 0; i < size; i++) {
    1215                final long value = values[i].get();
    1216                if (value != -1) {
    1217                    counter++;
    1218                    result = result * ((counter - 1) / (double) counter) +
    1219                            value/(double) counter;
    1220                }
    1221            }
    1222            return (long) result;
    1223        }
    1224
    1225        @Override
    1226        public String toString() {
    1227            final StringBuilder builder = new StringBuilder();
    1228            builder.append("StatsStore [values=");
    1229            builder.append(Arrays.toString(values));
    1230            builder.append(", size=");
    1231            builder.append(size);
    1232            builder.append(", index=");
    1233            builder.append(index);
    1234            builder.append("]");
    1235            return builder.toString();
    1236        }
    1237    }
    1238
    1239    /**
    1240     * The idle object eviction iterator. Holds a reference to the idle objects.
    1241     */
    1242    class EvictionIterator implements Iterator<PooledObject<T>> {
    1243
    1244        private final Deque<PooledObject<T>> idleObjects;
    1245        private final Iterator<PooledObject<T>> idleObjectIterator;
    1246
    1247        /**
    1248         * Create an EvictionIterator for the provided idle instance deque.
    1249         * @param idleObjects underlying deque
    1250         */
    1251        EvictionIterator(final Deque<PooledObject<T>> idleObjects) {
    1252            this.idleObjects = idleObjects;
    1253
    1254            if (getLifo()) {
    1255                idleObjectIterator = idleObjects.descendingIterator();
    1256            } else {
    1257                idleObjectIterator = idleObjects.iterator();
    1258            }
    1259        }
    1260
    1261        /**
    1262         * Returns the idle object deque referenced by this iterator.
    1263         * @return the idle object deque
    1264         */
    1265        public Deque<PooledObject<T>> getIdleObjects() {
    1266            return idleObjects;
    1267        }
    1268
    1269        /** {@inheritDoc} */
    1270        @Override
    1271        public boolean hasNext() {
    1272            return idleObjectIterator.hasNext();
    1273        }
    1274
    1275        /** {@inheritDoc} */
    1276        @Override
    1277        public PooledObject<T> next() {
    1278            return idleObjectIterator.next();
    1279        }
    1280
    1281        /** {@inheritDoc} */
    1282        @Override
    1283        public void remove() {
    1284            idleObjectIterator.remove();
    1285        }
    1286
    1287    }
    1288
    1289    /**
    1290     * Wrapper for objects under management by the pool.
    1291     *
    1292     * GenericObjectPool and GenericKeyedObjectPool maintain references to all
    1293     * objects under management using maps keyed on the objects. This wrapper
    1294     * class ensures that objects can work as hash keys.
    1295     *
    1296     * @param <T> type of objects in the pool
    1297     */
    1298    static class IdentityWrapper<T> {
    1299        /** Wrapped object */
    1300        private final T instance;
    1301
    1302        /**
    1303         * Create a wrapper for an instance.
    1304         *
    1305         * @param instance object to wrap
    1306         */
    1307        public IdentityWrapper(final T instance) {
    1308            this.instance = instance;
    1309        }
    1310
    1311        @Override
    1312        public int hashCode() {
    1313            return System.identityHashCode(instance);
    1314        }
    1315
    1316        @Override
    1317        @SuppressWarnings("rawtypes")
    1318        public boolean equals(final Object other) {
    1319            return  other instanceof IdentityWrapper &&
    1320                    ((IdentityWrapper) other).instance == instance;
    1321        }
    1322
    1323        /**
    1324         * @return the wrapped object
    1325         */
    1326        public T getObject() {
    1327            return instance;
    1328        }
    1329
    1330        @Override
    1331        public String toString() {
    1332            final StringBuilder builder = new StringBuilder();
    1333            builder.append("IdentityWrapper [instance=");
    1334            builder.append(instance);
    1335            builder.append("]");
    1336            return builder.toString();
    1337        }
    1338    }
    1339
    1340    @Override
    1341    protected void toStringAppendFields(final StringBuilder builder) {
    1342        builder.append("maxTotal=");
    1343        builder.append(maxTotal);
    1344        builder.append(", blockWhenExhausted=");
    1345        builder.append(blockWhenExhausted);
    1346        builder.append(", maxWaitMillis=");
    1347        builder.append(maxWaitMillis);
    1348        builder.append(", lifo=");
    1349        builder.append(lifo);
    1350        builder.append(", fairness=");
    1351        builder.append(fairness);
    1352        builder.append(", testOnCreate=");
    1353        builder.append(testOnCreate);
    1354        builder.append(", testOnBorrow=");
    1355        builder.append(testOnBorrow);
    1356        builder.append(", testOnReturn=");
    1357        builder.append(testOnReturn);
    1358        builder.append(", testWhileIdle=");
    1359        builder.append(testWhileIdle);
    1360        builder.append(", timeBetweenEvictionRunsMillis=");
    1361        builder.append(timeBetweenEvictionRunsMillis);
    1362        builder.append(", numTestsPerEvictionRun=");
    1363        builder.append(numTestsPerEvictionRun);
    1364        builder.append(", minEvictableIdleTimeMillis=");
    1365        builder.append(minEvictableIdleTimeMillis);
    1366        builder.append(", softMinEvictableIdleTimeMillis=");
    1367        builder.append(softMinEvictableIdleTimeMillis);
    1368        builder.append(", evictionPolicy=");
    1369        builder.append(evictionPolicy);
    1370        builder.append(", closeLock=");
    1371        builder.append(closeLock);
    1372        builder.append(", closed=");
    1373        builder.append(closed);
    1374        builder.append(", evictionLock=");
    1375        builder.append(evictionLock);
    1376        builder.append(", evictor=");
    1377        builder.append(evictor);
    1378        builder.append(", evictionIterator=");
    1379        builder.append(evictionIterator);
    1380        builder.append(", factoryClassLoader=");
    1381        builder.append(factoryClassLoader);
    1382        builder.append(", oname=");
    1383        builder.append(objectName);
    1384        builder.append(", creationStackTrace=");
    1385        builder.append(creationStackTrace);
    1386        builder.append(", borrowedCount=");
    1387        builder.append(borrowedCount);
    1388        builder.append(", returnedCount=");
    1389        builder.append(returnedCount);
    1390        builder.append(", createdCount=");
    1391        builder.append(createdCount);
    1392        builder.append(", destroyedCount=");
    1393        builder.append(destroyedCount);
    1394        builder.append(", destroyedByEvictorCount=");
    1395        builder.append(destroyedByEvictorCount);
    1396        builder.append(", destroyedByBorrowValidationCount=");
    1397        builder.append(destroyedByBorrowValidationCount);
    1398        builder.append(", activeTimes=");
    1399        builder.append(activeTimes);
    1400        builder.append(", idleTimes=");
    1401        builder.append(idleTimes);
    1402        builder.append(", waitTimes=");
    1403        builder.append(waitTimes);
    1404        builder.append(", maxBorrowWaitTimeMillis=");
    1405        builder.append(maxBorrowWaitTimeMillis);
    1406        builder.append(", swallowedExceptionListener=");
    1407        builder.append(swallowedExceptionListener);
    1408    }
    1409
    1410
    1411}