    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            if (null != evictor) {
    776                EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS);
    777                evictor = null;
    778                evictionIterator = null;
    779            }
    780            if (delay > 0) {
    781                evictor = new Evictor();
    782                EvictionTimer.schedule(evictor, delay, delay);
    783            }
    784        }
    785    }
    786
    787    /**
    788     * Stops the evictor.
    789     */
    790    void stopEvitor() {
    791        startEvictor(-1L);
    792    }
    793    /**
    794     * Tries to ensure that the configured minimum number of idle instances are
    795     * available in the pool.
    796     * @throws Exception if an error occurs creating idle instances
    797     */
    798    abstract void ensureMinIdle() throws Exception;
    799
    800
    801    // Monitoring (primarily JMX) related methods
    802
    803    /**
    804     * Provides the name under which the pool has been registered with the
    805     * platform MBean server or <code>null</code> if the pool has not been
    806     * registered.
    807     * @return the JMX name
    808     */
    809    public final ObjectName getJmxName() {
    810        return objectName;
    811    }
    812
    813    /**
    814     * Provides the stack trace for the call that created this pool. JMX
    815     * registration may trigger a memory leak so it is important that pools are
    816     * deregistered when no longer used by calling the {@link #close()} method.
    817     * This method is provided to assist with identifying code that creates but
    818     * does not close it thereby creating a memory leak.
    819     * @return pool creation stack trace
    820     */
    821    public final String getCreationStackTrace() {
    822        return creationStackTrace;
    823    }
    824
    825    /**
    826     * The total number of objects successfully borrowed from this pool over the
    827     * lifetime of the pool.
    828     * @return the borrowed object count
    829     */
    830    public final long getBorrowedCount() {
    831        return borrowedCount.get();
    832    }
    833
    834    /**
    835     * The total number of objects returned to this pool over the lifetime of
    836     * the pool. This excludes attempts to return the same object multiple
    837     * times.
    838     * @return the returned object count
    839     */
    840    public final long getReturnedCount() {
    841        return returnedCount.get();
    842    }
    843
    844    /**
    845     * The total number of objects created for this pool over the lifetime of
    846     * the pool.
    847     * @return the created object count
    848     */
    849    public final long getCreatedCount() {
    850        return createdCount.get();
    851    }
    852
    853    /**
    854     * The total number of objects destroyed by this pool over the lifetime of
    855     * the pool.
    856     * @return the destroyed object count
    857     */
    858    public final long getDestroyedCount() {
    859        return destroyedCount.get();
    860    }
    861
    862    /**
    863     * The total number of objects destroyed by the evictor associated with this
    864     * pool over the lifetime of the pool.
    865     * @return the evictor destroyed object count
    866     */
    867    public final long getDestroyedByEvictorCount() {
    868        return destroyedByEvictorCount.get();
    869    }
    870
    871    /**
    872     * The total number of objects destroyed by this pool as a result of failing
    873     * validation during <code>borrowObject()</code> over the lifetime of the
    874     * pool.
    875     * @return validation destroyed object count
    876     */
    877    public final long getDestroyedByBorrowValidationCount() {
    878        return destroyedByBorrowValidationCount.get();
    879    }
    880
    881    /**
    882     * The mean time objects are active for based on the last {@link
    883     * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
    884     * @return mean time an object has been checked out from the pool among
    885     * recently returned objects
    886     */
    887    public final long getMeanActiveTimeMillis() {
    888        return activeTimes.getMean();
    889    }
    890
    891    /**
    892     * The mean time objects are idle for based on the last {@link
    893     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    894     * @return mean time an object has been idle in the pool among recently
    895     * borrowed objects
    896     */
    897    public final long getMeanIdleTimeMillis() {
    898        return idleTimes.getMean();
    899    }
    900
    901    /**
    902     * The mean time threads wait to borrow an object based on the last {@link
    903     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    904     * @return mean time in milliseconds that a recently served thread has had
    905     * to wait to borrow an object from the pool
    906     */
    907    public final long getMeanBorrowWaitTimeMillis() {
    908        return waitTimes.getMean();
    909    }
    910
    911    /**
    912     * The maximum time a thread has waited to borrow objects from the pool.
    913     * @return maximum wait time in milliseconds since the pool was created
    914     */
    915    public final long getMaxBorrowWaitTimeMillis() {
    916        return maxBorrowWaitTimeMillis.get();
    917    }
    918
    919    /**
    920     * The number of instances currently idle in this pool.
    921     * @return count of instances available for checkout from the pool
    922     */
    923    public abstract int getNumIdle();
    924
    925    /**
    926     * The listener used (if any) to receive notifications of exceptions
    927     * unavoidably swallowed by the pool.
    928     *
    929     * @return The listener or <code>null</code> for no listener
    930     */
    931    public final SwallowedExceptionListener getSwallowedExceptionListener() {
    932        return swallowedExceptionListener;
    933    }
    934
    935    /**
    936     * The listener used (if any) to receive notifications of exceptions
    937     * unavoidably swallowed by the pool.
    938     *
    939     * @param swallowedExceptionListener    The listener or <code>null</code>
    940     *                                      for no listener
    941     */
    942    public final void setSwallowedExceptionListener(
    943            final SwallowedExceptionListener swallowedExceptionListener) {
    944        this.swallowedExceptionListener = swallowedExceptionListener;
    945    }
    946
    947    /**
    948     * Swallows an exception and notifies the configured listener for swallowed
    949     * exceptions queue.
    950     *
    951     * @param swallowException exception to be swallowed
    952     */
    953    final void swallowException(final Exception swallowException) {
    954        final SwallowedExceptionListener listener = getSwallowedExceptionListener();
    955
    956        if (listener == null) {
    957            return;
    958        }
    959
    960        try {
    961            listener.onSwallowException(swallowException);
    962        } catch (final VirtualMachineError e) {
    963            throw e;
    964        } catch (final Throwable t) {
    965            // Ignore. Enjoy the irony.
    966        }
    967    }
    968
    969    /**
    970     * Updates statistics after an object is borrowed from the pool.
    971     * @param p object borrowed from the pool
    972     * @param waitTime time (in milliseconds) that the borrowing thread had to wait
    973     */
    974    final void updateStatsBorrow(final PooledObject<T> p, final long waitTime) {
    975        borrowedCount.incrementAndGet();
    976        idleTimes.add(p.getIdleTimeMillis());
    977        waitTimes.add(waitTime);
    978
    979        // lock-free optimistic-locking maximum
    980        long currentMax;
    981        do {
    982            currentMax = maxBorrowWaitTimeMillis.get();
    983            if (currentMax >= waitTime) {
    984                break;
    985            }
    986        } while (!maxBorrowWaitTimeMillis.compareAndSet(currentMax, waitTime));
    987    }
    988
    989    /**
    990     * Updates statistics after an object is returned to the pool.
    991     * @param activeTime the amount of time (in milliseconds) that the returning
    992     * object was checked out
    993     */
    994    final void updateStatsReturn(final long activeTime) {
    995        returnedCount.incrementAndGet();
    996        activeTimes.add(activeTime);
    997    }
    998
    999    /**
    1000     * Marks the object as returning to the pool.
    1001     * @param pooledObject instance to return to the keyed pool
    1002     */
    1003    protected void markReturningState(final PooledObject<T> pooledObject) {
    1004        synchronized(pooledObject) {
    1005            final PooledObjectState state = pooledObject.getState();
    1006            if (state != PooledObjectState.ALLOCATED) {
    1007                throw new IllegalStateException(
    1008                        "Object has already been returned to this pool or is invalid");
    1009            }
    1010            pooledObject.markReturning(); // Keep from being marked abandoned
    1011        }
    1012    }
    1013
    1014    /**
    1015     * Unregisters this pool's MBean.
    1016     */
    1017    final void jmxUnregister() {
    1018        if (objectName != null) {
    1019            try {
    1020                ManagementFactory.getPlatformMBeanServer().unregisterMBean(
    1021                        objectName);
    1022            } catch (final MBeanRegistrationException | InstanceNotFoundException e) {
    1023                swallowException(e);
    1024            }
    1025        }
    1026    }
    1027
    1028    /**
    1029     * Registers the pool with the platform MBean server.
    1030     * The registered name will be
    1031     * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least
    1032     * integer greater than or equal to 1 such that the name is not already
    1033     * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
    1034     * returning null.
    1035     *
    1036     * @param config Pool configuration
    1037     * @param jmxNameBase default base JMX name for this pool
    1038     * @param jmxNamePrefix name prefix
    1039     * @return registered ObjectName, null if registration fails
    1040     */
    1041    private ObjectName jmxRegister(final BaseObjectPoolConfig<T> config,
    1042            final String jmxNameBase, String jmxNamePrefix) {
    1043        ObjectName newObjectName = null;
    1044        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    1045        int i = 1;
    1046        boolean registered = false;
    1047        String base = config.getJmxNameBase();
    1048        if (base == null) {
    1049            base = jmxNameBase;
    1050        }
    1051        while (!registered) {
    1052            try {
    1053                ObjectName objName;
    1054                // Skip the numeric suffix for the first pool in case there is
    1055                // only one so the names are cleaner.
    1056                if (i == 1) {
    1057                    objName = new ObjectName(base + jmxNamePrefix);
    1058                } else {
    1059                    objName = new ObjectName(base + jmxNamePrefix + i);
    1060                }
    1061                mbs.registerMBean(this, objName);
    1062                newObjectName = objName;
    1063                registered = true;
    1064            } catch (final MalformedObjectNameException e) {
    1065                if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals(
    1066                        jmxNamePrefix) && jmxNameBase.equals(base)) {
    1067                    // Shouldn't happen. Skip registration if it does.
    1068                    registered = true;
    1069                } else {
    1070                    // Must be an invalid name. Use the defaults instead.
    1071                    jmxNamePrefix =
    1072                            BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX;
    1073                    base = jmxNameBase;
    1074                }
    1075            } catch (final InstanceAlreadyExistsException e) {
    1076                // Increment the index and try again
    1077                i++;
    1078            } catch (final MBeanRegistrationException | NotCompliantMBeanException e) {
    1079                // Shouldn't happen. Skip registration if it does.
    1080                registered = true;
    1081            }
    1082        }
    1083        return newObjectName;
    1084    }
    1085
    1086    /**
    1087     * Gets the stack trace of an exception as a string.
    1088     * @param e exception to trace
    1089     * @return exception stack trace as a string
    1090     */
    1091    private String getStackTrace(final Exception e) {
    1092        // Need the exception in string form to prevent the retention of
    1093        // references to classes in the stack trace that could trigger a memory
    1094        // leak in a container environment.
    1095        final Writer w = new StringWriter();
    1096        final PrintWriter pw = new PrintWriter(w);
    1097        e.printStackTrace(pw);
    1098        return w.toString();
    1099    }
    1100
    1101    // Inner classes
    1102
    1103    /**
    1104     * The idle object evictor {@link TimerTask}.
    1105     *
    1106     * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
    1107     */
    1108    class Evictor implements Runnable {
    1109
    1110        private ScheduledFuture<?> scheduledFuture;
    1111
    1112        /**
    1113         * Run pool maintenance.  Evict objects qualifying for eviction and then
    1114         * ensure that the minimum number of idle instances are available.
    1115         * Since the Timer that invokes Evictors is shared for all Pools but
    1116         * pools may exist in different class loaders, the Evictor ensures that
    1117         * any actions taken are under the class loader of the factory
    1118         * associated with the pool.
    1119         */
    1120        @Override
    1121        public void run() {
    1122            final ClassLoader savedClassLoader =
    1123                    Thread.currentThread().getContextClassLoader();
    1124            try {
    1125                if (factoryClassLoader != null) {
    1126                    // Set the class loader for the factory
    1127                    final ClassLoader cl = factoryClassLoader.get();
    1128                    if (cl == null) {
    1129                        // The pool has been dereferenced and the class loader
    1130                        // GC'd. Cancel this timer so the pool can be GC'd as
    1131                        // well.
    1132                        cancel();
    1133                        return;
    1134                    }
    1135                    Thread.currentThread().setContextClassLoader(cl);
    1136                }
    1137
    1138                // Evict from the pool
    1139                try {
    1140                    evict();
    1141                } catch(final Exception e) {
    1142                    swallowException(e);
    1143                } catch(final OutOfMemoryError oome) {
    1144                    // Log problem but give evictor thread a chance to continue
    1145                    // in case error is recoverable
    1146                    oome.printStackTrace(System.err);
    1147                }
    1148                // Re-create idle instances.
    1149                try {
    1150                    ensureMinIdle();
    1151                } catch (final Exception e) {
    1152                    swallowException(e);
    1153                }
    1154            } finally {
    1155                // Restore the previous CCL
    1156                Thread.currentThread().setContextClassLoader(savedClassLoader);
    1157            }
    1158        }
    1159
    1160
    1161        void setScheduledFuture(final ScheduledFuture<?> scheduledFuture) {
    1162            this.scheduledFuture = scheduledFuture;
    1163        }
    1164
    1165
    1166        void cancel() {
    1167            scheduledFuture.cancel(false);
    1168        }
    1169    }
    1170
    1171    /**
    1172     * Maintains a cache of values for a single metric and reports
    1173     * statistics on the cached values.
    1174     */
    1175    private class StatsStore {
    1176
    1177        private final AtomicLong values[];
    1178        private final int size;
    1179        private int index;
    1180
    1181        /**
    1182         * Create a StatsStore with the given cache size.
    1183         *
    1184         * @param size number of values to maintain in the cache.
    1185         */
    1186        public StatsStore(final int size) {
    1187            this.size = size;
    1188            values = new AtomicLong[size];
    1189            for (int i = 0; i < size; i++) {
    1190                values[i] = new AtomicLong(-1);
    1191            }
    1192        }
    1193
    1194        /**
    1195         * Adds a value to the cache.  If the cache is full, one of the
    1196         * existing values is replaced by the new value.
    1197         *
    1198         * @param value new value to add to the cache.
    1199         */
    1200        public synchronized void add(final long value) {
    1201            values[index].set(value);
    1202            index++;
    1203            if (index == size) {
    1204                index = 0;
    1205            }
    1206        }
    1207
    1208        /**
    1209         * Returns the mean of the cached values.
    1210         *
    1211         * @return the mean of the cache, truncated to long
    1212         */
    1213        public long getMean() {
    1214            double result = 0;
    1215            int counter = 0;
    1216            for (int i = 0; i < size; i++) {
    1217                final long value = values[i].get();
    1218                if (value != -1) {
    1219                    counter++;
    1220                    result = result * ((counter - 1) / (double) counter) +
    1221                            value/(double) counter;
    1222                }
    1223            }
    1224            return (long) result;
    1225        }
    1226
    1227        @Override
    1228        public String toString() {
    1229            final StringBuilder builder = new StringBuilder();
    1230            builder.append("StatsStore [values=");
    1231            builder.append(Arrays.toString(values));
    1232            builder.append(", size=");
    1233            builder.append(size);
    1234            builder.append(", index=");
    1235            builder.append(index);
    1236            builder.append("]");
    1237            return builder.toString();
    1238        }
    1239    }
    1240
    1241    /**
    1242     * The idle object eviction iterator. Holds a reference to the idle objects.
    1243     */
    1244    class EvictionIterator implements Iterator<PooledObject<T>> {
    1245
    1246        private final Deque<PooledObject<T>> idleObjects;
    1247        private final Iterator<PooledObject<T>> idleObjectIterator;
    1248
    1249        /**
    1250         * Create an EvictionIterator for the provided idle instance deque.
    1251         * @param idleObjects underlying deque
    1252         */
    1253        EvictionIterator(final Deque<PooledObject<T>> idleObjects) {
    1254            this.idleObjects = idleObjects;
    1255
    1256            if (getLifo()) {
    1257                idleObjectIterator = idleObjects.descendingIterator();
    1258            } else {
    1259                idleObjectIterator = idleObjects.iterator();
    1260            }
    1261        }
    1262
    1263        /**
    1264         * Returns the idle object deque referenced by this iterator.
    1265         * @return the idle object deque
    1266         */
    1267        public Deque<PooledObject<T>> getIdleObjects() {
    1268            return idleObjects;
    1269        }
    1270
    1271        /** {@inheritDoc} */
    1272        @Override
    1273        public boolean hasNext() {
    1274            return idleObjectIterator.hasNext();
    1275        }
    1276
    1277        /** {@inheritDoc} */
    1278        @Override
    1279        public PooledObject<T> next() {
    1280            return idleObjectIterator.next();
    1281        }
    1282
    1283        /** {@inheritDoc} */
    1284        @Override
    1285        public void remove() {
    1286            idleObjectIterator.remove();
    1287        }
    1288
    1289    }
    1290
    1291    /**
    1292     * Wrapper for objects under management by the pool.
    1293     *
    1294     * GenericObjectPool and GenericKeyedObjectPool maintain references to all
    1295     * objects under management using maps keyed on the objects. This wrapper
    1296     * class ensures that objects can work as hash keys.
    1297     *
    1298     * @param <T> type of objects in the pool
    1299     */
    1300    static class IdentityWrapper<T> {
    1301        /** Wrapped object */
    1302        private final T instance;
    1303
    1304        /**
    1305         * Create a wrapper for an instance.
    1306         *
    1307         * @param instance object to wrap
    1308         */
    1309        public IdentityWrapper(final T instance) {
    1310            this.instance = instance;
    1311        }
    1312
    1313        @Override
    1314        public int hashCode() {
    1315            return System.identityHashCode(instance);
    1316        }
    1317
    1318        @Override
    1319        @SuppressWarnings("rawtypes")
    1320        public boolean equals(final Object other) {
    1321            return  other instanceof IdentityWrapper &&
    1322                    ((IdentityWrapper) other).instance == instance;
    1323        }
    1324
    1325        /**
    1326         * @return the wrapped object
    1327         */
    1328        public T getObject() {
    1329            return instance;
    1330        }
    1331
    1332        @Override
    1333        public String toString() {
    1334            final StringBuilder builder = new StringBuilder();
    1335            builder.append("IdentityWrapper [instance=");
    1336            builder.append(instance);
    1337            builder.append("]");
    1338            return builder.toString();
    1339        }
    1340    }
    1341
    1342    @Override
    1343    protected void toStringAppendFields(final StringBuilder builder) {
    1344        builder.append("maxTotal=");
    1345        builder.append(maxTotal);
    1346        builder.append(", blockWhenExhausted=");
    1347        builder.append(blockWhenExhausted);
    1348        builder.append(", maxWaitMillis=");
    1349        builder.append(maxWaitMillis);
    1350        builder.append(", lifo=");
    1351        builder.append(lifo);
    1352        builder.append(", fairness=");
    1353        builder.append(fairness);
    1354        builder.append(", testOnCreate=");
    1355        builder.append(testOnCreate);
    1356        builder.append(", testOnBorrow=");
    1357        builder.append(testOnBorrow);
    1358        builder.append(", testOnReturn=");
    1359        builder.append(testOnReturn);
    1360        builder.append(", testWhileIdle=");
    1361        builder.append(testWhileIdle);
    1362        builder.append(", timeBetweenEvictionRunsMillis=");
    1363        builder.append(timeBetweenEvictionRunsMillis);
    1364        builder.append(", numTestsPerEvictionRun=");
    1365        builder.append(numTestsPerEvictionRun);
    1366        builder.append(", minEvictableIdleTimeMillis=");
    1367        builder.append(minEvictableIdleTimeMillis);
    1368        builder.append(", softMinEvictableIdleTimeMillis=");
    1369        builder.append(softMinEvictableIdleTimeMillis);
    1370        builder.append(", evictionPolicy=");
    1371        builder.append(evictionPolicy);
    1372        builder.append(", closeLock=");
    1373        builder.append(closeLock);
    1374        builder.append(", closed=");
    1375        builder.append(closed);
    1376        builder.append(", evictionLock=");
    1377        builder.append(evictionLock);
    1378        builder.append(", evictor=");
    1379        builder.append(evictor);
    1380        builder.append(", evictionIterator=");
    1381        builder.append(evictionIterator);
    1382        builder.append(", factoryClassLoader=");
    1383        builder.append(factoryClassLoader);
    1384        builder.append(", oname=");
    1385        builder.append(objectName);
    1386        builder.append(", creationStackTrace=");
    1387        builder.append(creationStackTrace);
    1388        builder.append(", borrowedCount=");
    1389        builder.append(borrowedCount);
    1390        builder.append(", returnedCount=");
    1391        builder.append(returnedCount);
    1392        builder.append(", createdCount=");
    1393        builder.append(createdCount);
    1394        builder.append(", destroyedCount=");
    1395        builder.append(destroyedCount);
    1396        builder.append(", destroyedByEvictorCount=");
    1397        builder.append(destroyedByEvictorCount);
    1398        builder.append(", destroyedByBorrowValidationCount=");
    1399        builder.append(destroyedByBorrowValidationCount);
    1400        builder.append(", activeTimes=");
    1401        builder.append(activeTimes);
    1402        builder.append(", idleTimes=");
    1403        builder.append(idleTimes);
    1404        builder.append(", waitTimes=");
    1405        builder.append(waitTimes);
    1406        builder.append(", maxBorrowWaitTimeMillis=");
    1407        builder.append(maxBorrowWaitTimeMillis);
    1408        builder.append(", swallowedExceptionListener=");
    1409        builder.append(swallowedExceptionListener);
    1410    }
    1411
    1412
    1413}