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