    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 org.apache.commons.pool2.ObjectPool;
    020import org.apache.commons.pool2.PoolUtils;
    021import org.apache.commons.pool2.PooledObject;
    022import org.apache.commons.pool2.PooledObjectFactory;
    023import org.apache.commons.pool2.PooledObjectState;
    024import org.apache.commons.pool2.SwallowedExceptionListener;
    025import org.apache.commons.pool2.TrackedUse;
    026import org.apache.commons.pool2.UsageTracking;
    027
    028import java.util.ArrayList;
    029import java.util.HashSet;
    030import java.util.Iterator;
    031import java.util.Map;
    032import java.util.NoSuchElementException;
    033import java.util.Set;
    034import java.util.concurrent.ConcurrentHashMap;
    035import java.util.concurrent.TimeUnit;
    036import java.util.concurrent.atomic.AtomicLong;
    037
    038/**
    039 * A configurable {@link ObjectPool} implementation.
    040 * <p>
    041 * When coupled with the appropriate {@link PooledObjectFactory},
    042 * <code>GenericObjectPool</code> provides robust pooling functionality for
    043 * arbitrary objects.</p>
    044 * <p>
    045 * Optionally, one may configure the pool to examine and possibly evict objects
    046 * as they sit idle in the pool and to ensure that a minimum number of idle
    047 * objects are available. This is performed by an "idle object eviction" thread,
    048 * which runs asynchronously. Caution should be used when configuring this
    049 * optional feature. Eviction runs contend with client threads for access to
    050 * objects in the pool, so if they run too frequently performance issues may
    051 * result.</p>
    052 * <p>
    053 * The pool can also be configured to detect and remove "abandoned" objects,
    054 * i.e. objects that have been checked out of the pool but neither used nor
    055 * returned before the configured
    056 * {@link AbandonedConfig#getRemoveAbandonedTimeout() removeAbandonedTimeout}.
    057 * Abandoned object removal can be configured to happen when
    058 * <code>borrowObject</code> is invoked and the pool is close to starvation, or
    059 * it can be executed by the idle object evictor, or both. If pooled objects
    060 * implement the {@link TrackedUse} interface, their last use will be queried
    061 * using the <code>getLastUsed</code> method on that interface; otherwise
    062 * abandonment is determined by how long an object has been checked out from
    063 * the pool.</p>
    064 * <p>
    065 * Implementation note: To prevent possible deadlocks, care has been taken to
    066 * ensure that no call to a factory method will occur within a synchronization
    067 * block. See POOL-125 and DBCP-44 for more information.</p>
    068 * <p>
    069 * This class is intended to be thread-safe.</p>
    070 *
    071 * @see GenericKeyedObjectPool
    072 *
    073 * @param <T> Type of element pooled in this pool.
    074 *
    075 * @since 2.0
    076 */
    077public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
    078        implements ObjectPool<T>, GenericObjectPoolMXBean, UsageTracking<T> {
    079
    080    /**
    081     * Creates a new <code>GenericObjectPool</code> using defaults from
    082     * {@link GenericObjectPoolConfig}.
    083     *
    084     * @param factory The object factory to be used to create object instances
    085     *                used by this pool
    086     */
    087    public GenericObjectPool(final PooledObjectFactory<T> factory) {
    088        this(factory, new GenericObjectPoolConfig<T>());
    089    }
    090
    091    /**
    092     * Creates a new <code>GenericObjectPool</code> using a specific
    093     * configuration.
    094     *
    095     * @param factory   The object factory to be used to create object instances
    096     *                  used by this pool
    097     * @param config    The configuration to use for this pool instance. The
    098     *                  configuration is used by value. Subsequent changes to
    099     *                  the configuration object will not be reflected in the
    100     *                  pool.
    101     */
    102    public GenericObjectPool(final PooledObjectFactory<T> factory,
    103            final GenericObjectPoolConfig<T> config) {
    104
    105        super(config, ONAME_BASE, config.getJmxNamePrefix());
    106
    107        if (factory == null) {
    108            jmxUnregister(); // tidy up
    109            throw new IllegalArgumentException("factory may not be null");
    110        }
    111        this.factory = factory;
    112
    113        idleObjects = new LinkedBlockingDeque<>(config.getFairness());
    114
    115        setConfig(config);
    116    }
    117
    118    /**
    119     * Creates a new <code>GenericObjectPool</code> that tracks and destroys
    120     * objects that are checked out, but never returned to the pool.
    121     *
    122     * @param factory   The object factory to be used to create object instances
    123     *                  used by this pool
    124     * @param config    The base pool configuration to use for this pool instance.
    125     *                  The configuration is used by value. Subsequent changes to
    126     *                  the configuration object will not be reflected in the
    127     *                  pool.
    128     * @param abandonedConfig  Configuration for abandoned object identification
    129     *                         and removal.  The configuration is used by value.
    130     */
    131    public GenericObjectPool(final PooledObjectFactory<T> factory,
    132            final GenericObjectPoolConfig<T> config, final AbandonedConfig abandonedConfig) {
    133        this(factory, config);
    134        setAbandonedConfig(abandonedConfig);
    135    }
    136
    137    /**
    138     * Returns the cap on the number of "idle" instances in the pool. If maxIdle
    139     * is set too low on heavily loaded systems it is possible you will see
    140     * objects being destroyed and almost immediately new objects being created.
    141     * This is a result of the active threads momentarily returning objects
    142     * faster than they are requesting them, causing the number of idle
    143     * objects to rise above maxIdle. The best value for maxIdle for heavily
    144     * loaded system will vary but the default is a good starting point.
    145     *
    146     * @return the maximum number of "idle" instances that can be held in the
    147     *         pool or a negative value if there is no limit
    148     *
    149     * @see #setMaxIdle
    150     */
    151    @Override
    152    public int getMaxIdle() {
    153        return maxIdle;
    154    }
    155
    156    /**
    157     * Returns the cap on the number of "idle" instances in the pool. If maxIdle
    158     * is set too low on heavily loaded systems it is possible you will see
    159     * objects being destroyed and almost immediately new objects being created.
    160     * This is a result of the active threads momentarily returning objects
    161     * faster than they are requesting them, causing the number of idle
    162     * objects to rise above maxIdle. The best value for maxIdle for heavily
    163     * loaded system will vary but the default is a good starting point.
    164     *
    165     * @param maxIdle
    166     *            The cap on the number of "idle" instances in the pool. Use a
    167     *            negative value to indicate an unlimited number of idle
    168     *            instances
    169     *
    170     * @see #getMaxIdle
    171     */
    172    public void setMaxIdle(final int maxIdle) {
    173        this.maxIdle = maxIdle;
    174    }
    175
    176    /**
    177     * Sets the target for the minimum number of idle objects to maintain in
    178     * the pool. This setting only has an effect if it is positive and
    179     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
    180     * is the case, an attempt is made to ensure that the pool has the required
    181     * minimum number of instances during idle object eviction runs.
    182     * <p>
    183     * If the configured value of minIdle is greater than the configured value
    184     * for maxIdle then the value of maxIdle will be used instead.
    185     *
    186     * @param minIdle
    187     *            The minimum number of objects.
    188     *
    189     * @see #getMinIdle()
    190     * @see #getMaxIdle()
    191     * @see #getTimeBetweenEvictionRunsMillis()
    192     */
    193    public void setMinIdle(final int minIdle) {
    194        this.minIdle = minIdle;
    195    }
    196
    197    /**
    198     * Returns the target for the minimum number of idle objects to maintain in
    199     * the pool. This setting only has an effect if it is positive and
    200     * {@link #getTimeBetweenEvictionRunsMillis()} is greater than zero. If this
    201     * is the case, an attempt is made to ensure that the pool has the required
    202     * minimum number of instances during idle object eviction runs.
    203     * <p>
    204     * If the configured value of minIdle is greater than the configured value
    205     * for maxIdle then the value of maxIdle will be used instead.
    206     *
    207     * @return The minimum number of objects.
    208     *
    209     * @see #setMinIdle(int)
    210     * @see #setMaxIdle(int)
    211     * @see #setTimeBetweenEvictionRunsMillis(long)
    212     */
    213    @Override
    214    public int getMinIdle() {
    215        final int maxIdleSave = getMaxIdle();
    216        if (this.minIdle > maxIdleSave) {
    217            return maxIdleSave;
    218        }
    219        return minIdle;
    220    }
    221
    222    /**
    223     * Gets whether or not abandoned object removal is configured for this pool.
    224     *
    225     * @return true if this pool is configured to detect and remove
    226     * abandoned objects
    227     */
    228    @Override
    229    public boolean isAbandonedConfig() {
    230        return abandonedConfig != null;
    231    }
    232
    233    /**
    234     * Gets whether this pool identifies and logs any abandoned objects.
    235     *
    236     * @return {@code true} if abandoned object removal is configured for this
    237     *         pool and removal events are to be logged otherwise {@code false}
    238     *
    239     * @see AbandonedConfig#getLogAbandoned()
    240     */
    241    @Override
    242    public boolean getLogAbandoned() {
    243        final AbandonedConfig ac = this.abandonedConfig;
    244        return ac != null && ac.getLogAbandoned();
    245    }
    246
    247    /**
    248     * Gets whether a check is made for abandoned objects when an object is borrowed
    249     * from this pool.
    250     *
    251     * @return {@code true} if abandoned object removal is configured to be
    252     *         activated by borrowObject otherwise {@code false}
    253     *
    254     * @see AbandonedConfig#getRemoveAbandonedOnBorrow()
    255     */
    256    @Override
    257    public boolean getRemoveAbandonedOnBorrow() {
    258        final AbandonedConfig ac = this.abandonedConfig;
    259        return ac != null && ac.getRemoveAbandonedOnBorrow();
    260    }
    261
    262    /**
    263     * Gets whether a check is made for abandoned objects when the evictor runs.
    264     *
    265     * @return {@code true} if abandoned object removal is configured to be
    266     *         activated when the evictor runs otherwise {@code false}
    267     *
    268     * @see AbandonedConfig#getRemoveAbandonedOnMaintenance()
    269     */
    270    @Override
    271    public boolean getRemoveAbandonedOnMaintenance() {
    272        final AbandonedConfig ac = this.abandonedConfig;
    273        return ac != null && ac.getRemoveAbandonedOnMaintenance();
    274    }
    275
    276    /**
    277     * Obtains the timeout before which an object will be considered to be
    278     * abandoned by this pool.
    279     *
    280     * @return The abandoned object timeout in seconds if abandoned object
    281     *         removal is configured for this pool; Integer.MAX_VALUE otherwise.
    282     *
    283     * @see AbandonedConfig#getRemoveAbandonedTimeout()
    284     */
    285    @Override
    286    public int getRemoveAbandonedTimeout() {
    287        final AbandonedConfig ac = this.abandonedConfig;
    288        return ac != null ? ac.getRemoveAbandonedTimeout() : Integer.MAX_VALUE;
    289    }
    290
    291
    292    /**
    293     * Sets the base pool configuration.
    294     *
    295     * @param conf the new configuration to use. This is used by value.
    296     *
    297     * @see GenericObjectPoolConfig
    298     */
    299    public void setConfig(final GenericObjectPoolConfig<T> conf) {
    300        setLifo(conf.getLifo());
    301        setMaxIdle(conf.getMaxIdle());
    302        setMinIdle(conf.getMinIdle());
    303        setMaxTotal(conf.getMaxTotal());
    304        setMaxWaitMillis(conf.getMaxWaitMillis());
    305        setBlockWhenExhausted(conf.getBlockWhenExhausted());
    306        setTestOnCreate(conf.getTestOnCreate());
    307        setTestOnBorrow(conf.getTestOnBorrow());
    308        setTestOnReturn(conf.getTestOnReturn());
    309        setTestWhileIdle(conf.getTestWhileIdle());
    310        setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
    311        setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
    312        setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
    313        setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
    314        final EvictionPolicy<T> policy = conf.getEvictionPolicy();
    315        if (policy == null) {
    316            // Use the class name (pre-2.6.0 compatible)
    317            setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
    318        } else {
    319            // Otherwise, use the class (2.6.0 feature)
    320            setEvictionPolicy(policy);
    321        }
    322        setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
    323    }
    324
    325    /**
    326     * Sets the abandoned object removal configuration.
    327     *
    328     * @param abandonedConfig the new configuration to use. This is used by value.
    329     *
    330     * @see AbandonedConfig
    331     */
    332    public void setAbandonedConfig(final AbandonedConfig abandonedConfig) {
    333        if (abandonedConfig == null) {
    334            this.abandonedConfig = null;
    335        } else {
    336            this.abandonedConfig = new AbandonedConfig();
    337            this.abandonedConfig.setLogAbandoned(abandonedConfig.getLogAbandoned());
    338            this.abandonedConfig.setLogWriter(abandonedConfig.getLogWriter());
    339            this.abandonedConfig.setRemoveAbandonedOnBorrow(abandonedConfig.getRemoveAbandonedOnBorrow());
    340            this.abandonedConfig.setRemoveAbandonedOnMaintenance(abandonedConfig.getRemoveAbandonedOnMaintenance());
    341            this.abandonedConfig.setRemoveAbandonedTimeout(abandonedConfig.getRemoveAbandonedTimeout());
    342            this.abandonedConfig.setUseUsageTracking(abandonedConfig.getUseUsageTracking());
    343            this.abandonedConfig.setRequireFullStackTrace(abandonedConfig.getRequireFullStackTrace());
    344        }
    345    }
    346
    347    /**
    348     * Obtains a reference to the factory used to create, destroy and validate
    349     * the objects used by this pool.
    350     *
    351     * @return the factory
    352     */
    353    public PooledObjectFactory<T> getFactory() {
    354        return factory;
    355    }
    356
    357    /**
    358     * Equivalent to <code>{@link #borrowObject(long)
    359     * borrowObject}({@link #getMaxWaitMillis()})</code>.
    360     * <p>
    361     * {@inheritDoc}
    362     */
    363    @Override
    364    public T borrowObject() throws Exception {
    365        return borrowObject(getMaxWaitMillis());
    366    }
    367
    368    /**
    369     * Borrows an object from the pool using the specific waiting time which only
    370     * applies if {@link #getBlockWhenExhausted()} is true.
    371     * <p>
    372     * If there is one or more idle instance available in the pool, then an
    373     * idle instance will be selected based on the value of {@link #getLifo()},
    374     * activated and returned. If activation fails, or {@link #getTestOnBorrow()
    375     * testOnBorrow} is set to <code>true</code> and validation fails, the
    376     * instance is destroyed and the next available instance is examined. This
    377     * continues until either a valid instance is returned or there are no more
    378     * idle instances available.
    379     * <p>
    380     * If there are no idle instances available in the pool, behavior depends on
    381     * the {@link #getMaxTotal() maxTotal}, (if applicable)
    382     * {@link #getBlockWhenExhausted()} and the value passed in to the
    383     * <code>borrowMaxWaitMillis</code> parameter. If the number of instances
    384     * checked out from the pool is less than <code>maxTotal,</code> a new
    385     * instance is created, activated and (if applicable) validated and returned
    386     * to the caller. If validation fails, a <code>NoSuchElementException</code>
    387     * is thrown.
    388     * <p>
    389     * If the pool is exhausted (no available idle instances and no capacity to
    390     * create new ones), this method will either block (if
    391     * {@link #getBlockWhenExhausted()} is true) or throw a
    392     * <code>NoSuchElementException</code> (if
    393     * {@link #getBlockWhenExhausted()} is false). The length of time that this
    394     * method will block when {@link #getBlockWhenExhausted()} is true is
    395     * determined by the value passed in to the <code>borrowMaxWaitMillis</code>
    396     * parameter.
    397     * <p>
    398     * When the pool is exhausted, multiple calling threads may be
    399     * simultaneously blocked waiting for instances to become available. A
    400     * "fairness" algorithm has been implemented to ensure that threads receive
    401     * available instances in request arrival order.
    402     *
    403     * @param borrowMaxWaitMillis The time to wait in milliseconds for an object
    404     *                            to become available
    405     *
    406     * @return object instance from the pool
    407     *
    408     * @throws NoSuchElementException if an instance cannot be returned
    409     *
    410     * @throws Exception if an object instance cannot be returned due to an
    411     *                   error
    412     */
    413    public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
    414        assertOpen();
    415
    416        final AbandonedConfig ac = this.abandonedConfig;
    417        if (ac != null && ac.getRemoveAbandonedOnBorrow() &&
    418                (getNumIdle() < 2) &&
    419                (getNumActive() > getMaxTotal() - 3) ) {
    420            removeAbandoned(ac);
    421        }
    422
    423        PooledObject<T> p = null;
    424
    425        // Get local copy of current config so it is consistent for entire
    426        // method execution
    427        final boolean blockWhenExhausted = getBlockWhenExhausted();
    428
    429        boolean create;
    430        final long waitTime = System.currentTimeMillis();
    431
    432        while (p == null) {
    433            create = false;
    434            p = idleObjects.pollFirst();
    435            if (p == null) {
    436                p = create();
    437                if (p != null) {
    438                    create = true;
    439                }
    440            }
    441            if (blockWhenExhausted) {
    442                if (p == null) {
    443                    if (borrowMaxWaitMillis < 0) {
    444                        p = idleObjects.takeFirst();
    445                    } else {
    446                        p = idleObjects.pollFirst(borrowMaxWaitMillis,
    447                                TimeUnit.MILLISECONDS);
    448                    }
    449                }
    450                if (p == null) {
    451                    throw new NoSuchElementException(
    452                            "Timeout waiting for idle object");
    453                }
    454            } else {
    455                if (p == null) {
    456                    throw new NoSuchElementException("Pool exhausted");
    457                }
    458            }
    459            if (!p.allocate()) {
    460                p = null;
    461            }
    462
    463            if (p != null) {
    464                try {
    465                    factory.activateObject(p);
    466                } catch (final Exception e) {
    467                    try {
    468                        destroy(p);
    469                    } catch (final Exception e1) {
    470                        // Ignore - activation failure is more important
    471                    }
    472                    p = null;
    473                    if (create) {
    474                        final NoSuchElementException nsee = new NoSuchElementException(
    475                                "Unable to activate object");
    476                        nsee.initCause(e);
    477                        throw nsee;
    478                    }
    479                }
    480                if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) {
    481                    boolean validate = false;
    482                    Throwable validationThrowable = null;
    483                    try {
    484                        validate = factory.validateObject(p);
    485                    } catch (final Throwable t) {
    486                        PoolUtils.checkRethrow(t);
    487                        validationThrowable = t;
    488                    }
    489                    if (!validate) {
    490                        try {
    491                            destroy(p);
    492                            destroyedByBorrowValidationCount.incrementAndGet();
    493                        } catch (final Exception e) {
    494                            // Ignore - validation failure is more important
    495                        }
    496                        p = null;
    497                        if (create) {
    498                            final NoSuchElementException nsee = new NoSuchElementException(
    499                                    "Unable to validate object");
    500                            nsee.initCause(validationThrowable);
    501                            throw nsee;
    502                        }
    503                    }
    504                }
    505            }
    506        }
    507
    508        updateStatsBorrow(p, System.currentTimeMillis() - waitTime);
    509
    510        return p.getObject();
    511    }
    512
    513    /**
    514     * {@inheritDoc}
    515     * <p>
    516     * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
    517     * number of idle instances has reached this value, the returning instance
    518     * is destroyed.
    519     * <p>
    520     * If {@link #getTestOnReturn() testOnReturn} == true, the returning
    521     * instance is validated before being returned to the idle instance pool. In
    522     * this case, if validation fails, the instance is destroyed.
    523     * <p>
    524     * Exceptions encountered destroying objects for any reason are swallowed
    525     * but notified via a {@link SwallowedExceptionListener}.
    526     */
    527    @Override
    528    public void returnObject(final T obj) {
    529        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
    530
    531        if (p == null) {
    532            if (!isAbandonedConfig()) {
    533                throw new IllegalStateException(
    534                        "Returned object not currently part of this pool");
    535            }
    536            return; // Object was abandoned and removed
    537        }
    538
    539        markReturningState(p);
    540
    541        final long activeTime = p.getActiveTimeMillis();
    542
    543        if (getTestOnReturn() && !factory.validateObject(p)) {
    544            try {
    545                destroy(p);
    546            } catch (final Exception e) {
    547                swallowException(e);
    548            }
    549            try {
    550                ensureIdle(1, false);
    551            } catch (final Exception e) {
    552                swallowException(e);
    553            }
    554            updateStatsReturn(activeTime);
    555            return;
    556        }
    557
    558        try {
    559            factory.passivateObject(p);
    560        } catch (final Exception e1) {
    561            swallowException(e1);
    562            try {
    563                destroy(p);
    564            } catch (final Exception e) {
    565                swallowException(e);
    566            }
    567            try {
    568                ensureIdle(1, false);
    569            } catch (final Exception e) {
    570                swallowException(e);
    571            }
    572            updateStatsReturn(activeTime);
    573            return;
    574        }
    575
    576        if (!p.deallocate()) {
    577            throw new IllegalStateException(
    578                    "Object has already been returned to this pool or is invalid");
    579        }
    580
    581        final int maxIdleSave = getMaxIdle();
    582        if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
    583            try {
    584                destroy(p);
    585            } catch (final Exception e) {
    586                swallowException(e);
    587            }
    588        } else {
    589            if (getLifo()) {
    590                idleObjects.addFirst(p);
    591            } else {
    592                idleObjects.addLast(p);
    593            }
    594            if (isClosed()) {
    595                // Pool closed while object was being added to idle objects.
    596                // Make sure the returned object is destroyed rather than left
    597                // in the idle object pool (which would effectively be a leak)
    598                clear();
    599            }
    600        }
    601        updateStatsReturn(activeTime);
    602    }
    603
    604    /**
    605     * {@inheritDoc}
    606     * <p>
    607     * Activation of this method decrements the active count and attempts to
    608     * destroy the instance.
    609     *
    610     * @throws Exception             if an exception occurs destroying the
    611     *                               object
    612     * @throws IllegalStateException if obj does not belong to this pool
    613     */
    614    @Override
    615    public void invalidateObject(final T obj) throws Exception {
    616        final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
    617        if (p == null) {
    618            if (isAbandonedConfig()) {
    619                return;
    620            }
    621            throw new IllegalStateException(
    622                    "Invalidated object not currently part of this pool");
    623        }
    624        synchronized (p) {
    625            if (p.getState() != PooledObjectState.INVALID) {
    626                destroy(p);
    627            }
    628        }
    629        ensureIdle(1, false);
    630    }
    631
    632    /**
    633     * Clears any objects sitting idle in the pool by removing them from the
    634     * idle instance pool and then invoking the configured
    635     * {@link PooledObjectFactory#destroyObject(PooledObject)} method on each
    636     * idle instance.
    637     * <p>
    638     * Implementation notes:
    639     * <ul>
    640     * <li>This method does not destroy or effect in any way instances that are
    641     * checked out of the pool when it is invoked.</li>
    642     * <li>Invoking this method does not prevent objects being returned to the
    643     * idle instance pool, even during its execution. Additional instances may
    644     * be returned while removed items are being destroyed.</li>
    645     * <li>Exceptions encountered destroying idle instances are swallowed
    646     * but notified via a {@link SwallowedExceptionListener}.</li>
    647     * </ul>
    648     */
    649    @Override
    650    public void clear() {
    651        PooledObject<T> p = idleObjects.poll();
    652
    653        while (p != null) {
    654            try {
    655                destroy(p);
    656            } catch (final Exception e) {
    657                swallowException(e);
    658            }
    659            p = idleObjects.poll();
    660        }
    661    }
    662
    663    @Override
    664    public int getNumActive() {
    665        return allObjects.size() - idleObjects.size();
    666    }
    667
    668    @Override
    669    public int getNumIdle() {
    670        return idleObjects.size();
    671    }
    672
    673    /**
    674     * Closes the pool. Once the pool is closed, {@link #borrowObject()} will
    675     * fail with IllegalStateException, but {@link #returnObject(Object)} and
    676     * {@link #invalidateObject(Object)} will continue to work, with returned
    677     * objects destroyed on return.
    678     * <p>
    679     * Destroys idle instances in the pool by invoking {@link #clear()}.
    680     */
    681    @Override
    682    public void close() {
    683        if (isClosed()) {
    684            return;
    685        }
    686
    687        synchronized (closeLock) {
    688            if (isClosed()) {
    689                return;
    690            }
    691
    692            // Stop the evictor before the pool is closed since evict() calls
    693            // assertOpen()
    694            startEvictor(-1L);
    695
    696            closed = true;
    697            // This clear removes any idle objects
    698            clear();
    699
    700            jmxUnregister();
    701
    702            // Release any threads that were waiting for an object
    703            idleObjects.interuptTakeWaiters();
    704        }
    705    }
    706
    707    /**
    708     * {@inheritDoc}
    709     * <p>
    710     * Successive activations of this method examine objects in sequence,
    711     * cycling through objects in oldest-to-youngest order.
    712     */
    713    @Override
    714    public void evict() throws Exception {
    715        assertOpen();
    716
    717        if (idleObjects.size() > 0) {
    718
    719            PooledObject<T> underTest = null;
    720            final EvictionPolicy<T> evictionPolicy = getEvictionPolicy();
    721
    722            synchronized (evictionLock) {
    723                final EvictionConfig evictionConfig = new EvictionConfig(
    724                        getMinEvictableIdleTimeMillis(),
    725                        getSoftMinEvictableIdleTimeMillis(),
    726                        getMinIdle());
    727
    728                final boolean testWhileIdle = getTestWhileIdle();
    729
    730                for (int i = 0, m = getNumTests(); i < m; i++) {
    731                    if (evictionIterator == null || !evictionIterator.hasNext()) {
    732                        evictionIterator = new EvictionIterator(idleObjects);
    733                    }
    734                    if (!evictionIterator.hasNext()) {
    735                        // Pool exhausted, nothing to do here
    736                        return;
    737                    }
    738
    739                    try {
    740                        underTest = evictionIterator.next();
    741                    } catch (final NoSuchElementException nsee) {
    742                        // Object was borrowed in another thread
    743                        // Don't count this as an eviction test so reduce i;
    744                        i--;
    745                        evictionIterator = null;
    746                        continue;
    747                    }
    748
    749                    if (!underTest.startEvictionTest()) {
    750                        // Object was borrowed in another thread
    751                        // Don't count this as an eviction test so reduce i;
    752                        i--;
    753                        continue;
    754                    }
    755
    756                    // User provided eviction policy could throw all sorts of
    757                    // crazy exceptions. Protect against such an exception
    758                    // killing the eviction thread.
    759                    boolean evict;
    760                    try {
    761                        evict = evictionPolicy.evict(evictionConfig, underTest,
    762                                idleObjects.size());
    763                    } catch (final Throwable t) {
    764                        // Slightly convoluted as SwallowedExceptionListener
    765                        // uses Exception rather than Throwable
    766                        PoolUtils.checkRethrow(t);
    767                        swallowException(new Exception(t));
    768                        // Don't evict on error conditions
    769                        evict = false;
    770                    }
    771
    772                    if (evict) {
    773                        destroy(underTest);
    774                        destroyedByEvictorCount.incrementAndGet();
    775                    } else {
    776                        if (testWhileIdle) {
    777                            boolean active = false;
    778                            try {
    779                                factory.activateObject(underTest);
    780                                active = true;
    781                            } catch (final Exception e) {
    782                                destroy(underTest);
    783                                destroyedByEvictorCount.incrementAndGet();
    784                            }
    785                            if (active) {
    786                                if (!factory.validateObject(underTest)) {
    787                                    destroy(underTest);
    788                                    destroyedByEvictorCount.incrementAndGet();
    789                                } else {
    790                                    try {
    791                                        factory.passivateObject(underTest);
    792                                    } catch (final Exception e) {
    793                                        destroy(underTest);
    794                                        destroyedByEvictorCount.incrementAndGet();
    795                                    }
    796                                }
    797                            }
    798                        }
    799                        if (!underTest.endEvictionTest(idleObjects)) {
    800                            // TODO - May need to add code here once additional
    801                            // states are used
    802                        }
    803                    }
    804                }
    805            }
    806        }
    807        final AbandonedConfig ac = this.abandonedConfig;
    808        if (ac != null && ac.getRemoveAbandonedOnMaintenance()) {
    809            removeAbandoned(ac);
    810        }
    811    }
    812
    813    /**
    814     * Tries to ensure that {@link #getMinIdle()} idle instances are available
    815     * in the pool.
    816     *
    817     * @throws Exception If the associated factory throws an exception
    818     * @since 2.4
    819     */
    820    public void preparePool() throws Exception {
    821        if (getMinIdle() < 1) {
    822            return;
    823        }
    824        ensureMinIdle();
    825    }
    826
    827    /**
    828     * Attempts to create a new wrapped pooled object.
    829     * <p>
    830     * If there are {@link #getMaxTotal()} objects already in circulation
    831     * or in process of being created, this method returns null.
    832     *
    833     * @return The new wrapped pooled object
    834     *
    835     * @throws Exception if the object factory's {@code makeObject} fails
    836     */
    837    private PooledObject<T> create() throws Exception {
    838        int localMaxTotal = getMaxTotal();
    839        // This simplifies the code later in this method
    840        if (localMaxTotal < 0) {
    841            localMaxTotal = Integer.MAX_VALUE;
    842        }
    843
    844        // Flag that indicates if create should:
    845        // - TRUE:  call the factory to create an object
    846        // - FALSE: return null
    847        // - null:  loop and re-test the condition that determines whether to
    848        //          call the factory
    849        Boolean create = null;
    850        while (create == null) {
    851            synchronized (makeObjectCountLock) {
    852                final long newCreateCount = createCount.incrementAndGet();
    853                if (newCreateCount > localMaxTotal) {
    854                    // The pool is currently at capacity or in the process of
    855                    // making enough new objects to take it to capacity.
    856                    createCount.decrementAndGet();
    857                    if (makeObjectCount == 0) {
    858                        // There are no makeObject() calls in progress so the
    859                        // pool is at capacity. Do not attempt to create a new
    860                        // object. Return and wait for an object to be returned
    861                        create = Boolean.FALSE;
    862                    } else {
    863                        // There are makeObject() calls in progress that might
    864                        // bring the pool to capacity. Those calls might also
    865                        // fail so wait until they complete and then re-test if
    866                        // the pool is at capacity or not.
    867                        makeObjectCountLock.wait();
    868                    }
    869                } else {
    870                    // The pool is not at capacity. Create a new object.
    871                    makeObjectCount++;
    872                    create = Boolean.TRUE;
    873                }
    874            }
    875        }
    876
    877        if (!create.booleanValue()) {
    878            return null;
    879        }
    880
    881        final PooledObject<T> p;
    882        try {
    883            p = factory.makeObject();
    884        } catch (final Throwable e) {
    885            createCount.decrementAndGet();
    886            throw e;
    887        } finally {
    888            synchronized (makeObjectCountLock) {
    889                makeObjectCount--;
    890                makeObjectCountLock.notifyAll();
    891            }
    892        }
    893
    894        final AbandonedConfig ac = this.abandonedConfig;
    895        if (ac != null && ac.getLogAbandoned()) {
    896            p.setLogAbandoned(true);
    897            // TODO: in 3.0, this can use the method defined on PooledObject
    898            if (p instanceof DefaultPooledObject<?>) {
    899                ((DefaultPooledObject<T>) p).setRequireFullStackTrace(ac.getRequireFullStackTrace());
    900            }
    901        }
    902
    903        createdCount.incrementAndGet();
    904        allObjects.put(new IdentityWrapper<>(p.getObject()), p);
    905        return p;
    906    }
    907
    908    /**
    909     * Destroys a wrapped pooled object.
    910     *
    911     * @param toDestroy The wrapped pooled object to destroy
    912     *
    913     * @throws Exception If the factory fails to destroy the pooled object
    914     *                   cleanly
    915     */
    916    private void destroy(final PooledObject<T> toDestroy) throws Exception {
    917        toDestroy.invalidate();
    918        idleObjects.remove(toDestroy);
    919        allObjects.remove(new IdentityWrapper<>(toDestroy.getObject()));
    920        try {
    921            factory.destroyObject(toDestroy);
    922        } finally {
    923            destroyedCount.incrementAndGet();
    924            createCount.decrementAndGet();
    925        }
    926    }
    927
    928    @Override
    929    void ensureMinIdle() throws Exception {
    930        ensureIdle(getMinIdle(), true);
    931    }
    932
    933    /**
    934     * Tries to ensure that {@code idleCount} idle instances exist in the pool.
    935     * <p>
    936     * Creates and adds idle instances until either {@link #getNumIdle()} reaches {@code idleCount}
    937     * or the total number of objects (idle, checked out, or being created) reaches
    938     * {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless
    939     * there are threads waiting to check out instances from the pool.
    940     *
    941     * @param idleCount the number of idle instances desired
    942     * @param always true means create instances even if the pool has no threads waiting
    943     * @throws Exception if the factory's makeObject throws
    944     */
    945    private void ensureIdle(final int idleCount, final boolean always) throws Exception {
    946        if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) {
    947            return;
    948        }
    949
    950        while (idleObjects.size() < idleCount) {
    951            final PooledObject<T> p = create();
    952            if (p == null) {
    953                // Can't create objects, no reason to think another call to
    954                // create will work. Give up.
    955                break;
    956            }
    957            if (getLifo()) {
    958                idleObjects.addFirst(p);
    959            } else {
    960                idleObjects.addLast(p);
    961            }
    962        }
    963        if (isClosed()) {
    964            // Pool closed while object was being added to idle objects.
    965            // Make sure the returned object is destroyed rather than left
    966            // in the idle object pool (which would effectively be a leak)
    967            clear();
    968        }
    969    }
    970
    971    /**
    972     * Creates an object, and place it into the pool. addObject() is useful for
    973     * "pre-loading" a pool with idle objects.
    974     * <p>
    975     * If there is no capacity available to add to the pool, this is a no-op
    976     * (no exception, no impact to the pool). </p>
    977     */
    978    @Override
    979    public void addObject() throws Exception {
    980        assertOpen();
    981        if (factory == null) {
    982            throw new IllegalStateException(
    983                    "Cannot add objects without a factory.");
    984        }
    985        final PooledObject<T> p = create();
    986        addIdleObject(p);
    987    }
    988
    989    /**
    990     * Adds the provided wrapped pooled object to the set of idle objects for
    991     * this pool. The object must already be part of the pool.  If {@code p}
    992     * is null, this is a no-op (no exception, but no impact on the pool).
    993     *
    994     * @param p The object to make idle
    995     *
    996     * @throws Exception If the factory fails to passivate the object
    997     */
    998    private void addIdleObject(final PooledObject<T> p) throws Exception {
    999        if (p != null) {
    1000            factory.passivateObject(p);
    1001            if (getLifo()) {
    1002                idleObjects.addFirst(p);
    1003            } else {
    1004                idleObjects.addLast(p);
    1005            }
    1006        }
    1007    }
    1008
    1009    /**
    1010     * Calculates the number of objects to test in a run of the idle object
    1011     * evictor.
    1012     *
    1013     * @return The number of objects to test for validity
    1014     */
    1015    private int getNumTests() {
    1016        final int numTestsPerEvictionRun = getNumTestsPerEvictionRun();
    1017        if (numTestsPerEvictionRun >= 0) {
    1018            return Math.min(numTestsPerEvictionRun, idleObjects.size());
    1019        }
    1020        return (int) (Math.ceil(idleObjects.size() /
    1021                Math.abs((double) numTestsPerEvictionRun)));
    1022    }
    1023
    1024    /**
    1025     * Recovers abandoned objects which have been checked out but
    1026     * not used since longer than the removeAbandonedTimeout.
    1027     *
    1028     * @param ac The configuration to use to identify abandoned objects
    1029     */
    1030    private void removeAbandoned(final AbandonedConfig ac) {
    1031        // Generate a list of abandoned objects to remove
    1032        final long now = System.currentTimeMillis();
    1033        final long timeout =
    1034                now - (ac.getRemoveAbandonedTimeout() * 1000L);
    1035        final ArrayList<PooledObject<T>> remove = new ArrayList<>();
    1036        final Iterator<PooledObject<T>> it = allObjects.values().iterator();
    1037        while (it.hasNext()) {
    1038            final PooledObject<T> pooledObject = it.next();
    1039            synchronized (pooledObject) {
    1040                if (pooledObject.getState() == PooledObjectState.ALLOCATED &&
    1041                        pooledObject.getLastUsedTime() <= timeout) {
    1042                    pooledObject.markAbandoned();
    1043                    remove.add(pooledObject);
    1044                }
    1045            }
    1046        }
    1047
    1048        // Now remove the abandoned objects
    1049        final Iterator<PooledObject<T>> itr = remove.iterator();
    1050        while (itr.hasNext()) {
    1051            final PooledObject<T> pooledObject = itr.next();
    1052            if (ac.getLogAbandoned()) {
    1053                pooledObject.printStackTrace(ac.getLogWriter());
    1054            }
    1055            try {
    1056                invalidateObject(pooledObject.getObject());
    1057            } catch (final Exception e) {
    1058                e.printStackTrace();
    1059            }
    1060        }
    1061    }
    1062
    1063
    1064    //--- Usage tracking support -----------------------------------------------
    1065
    1066    @Override
    1067    public void use(final T pooledObject) {
    1068        final AbandonedConfig ac = this.abandonedConfig;
    1069        if (ac != null && ac.getUseUsageTracking()) {
    1070            final PooledObject<T> wrapper = allObjects.get(new IdentityWrapper<>(pooledObject));
    1071            wrapper.use();
    1072        }
    1073    }
    1074
    1075
    1076    //--- JMX support ----------------------------------------------------------
    1077
    1078    private volatile String factoryType = null;
    1079
    1080    /**
    1081     * Returns an estimate of the number of threads currently blocked waiting for
    1082     * an object from the pool. This is intended for monitoring only, not for
    1083     * synchronization control.
    1084     *
    1085     * @return The estimate of the number of threads currently blocked waiting
    1086     *         for an object from the pool
    1087     */
    1088    @Override
    1089    public int getNumWaiters() {
    1090        if (getBlockWhenExhausted()) {
    1091            return idleObjects.getTakeQueueLength();
    1092        }
    1093        return 0;
    1094    }
    1095
    1096    /**
    1097     * Returns the type - including the specific type rather than the generic -
    1098     * of the factory.
    1099     *
    1100     * @return A string representation of the factory type
    1101     */
    1102    @Override
    1103    public String getFactoryType() {
    1104        // Not thread safe. Accept that there may be multiple evaluations.
    1105        if (factoryType == null) {
    1106            final StringBuilder result = new StringBuilder();
    1107            result.append(factory.getClass().getName());
    1108            result.append('<');
    1109            final Class<?> pooledObjectType =
    1110                    PoolImplUtils.getFactoryType(factory.getClass());
    1111            result.append(pooledObjectType.getName());
    1112            result.append('>');
    1113            factoryType = result.toString();
    1114        }
    1115        return factoryType;
    1116    }
    1117
    1118    /**
    1119     * Provides information on all the objects in the pool, both idle (waiting
    1120     * to be borrowed) and active (currently borrowed).
    1121     * <p>
    1122     * Note: This is named listAllObjects so it is presented as an operation via
    1123     * JMX. That means it won't be invoked unless the explicitly requested
    1124     * whereas all attributes will be automatically requested when viewing the
    1125     * attributes for an object in a tool like JConsole.
    1126     *
    1127     * @return Information grouped on all the objects in the pool
    1128     */
    1129    @Override
    1130    public Set<DefaultPooledObjectInfo> listAllObjects() {
    1131        final Set<DefaultPooledObjectInfo> result =
    1132                new HashSet<>(allObjects.size());
    1133        for (final PooledObject<T> p : allObjects.values()) {
    1134            result.add(new DefaultPooledObjectInfo(p));
    1135        }
    1136        return result;
    1137    }
    1138
    1139    // --- configuration attributes --------------------------------------------
    1140
    1141    private volatile int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
    1142    private volatile int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
    1143    private final PooledObjectFactory<T> factory;
    1144
    1145
    1146    // --- internal attributes -------------------------------------------------
    1147
    1148    /*
    1149     * All of the objects currently associated with this pool in any state. It
    1150     * excludes objects that have been destroyed. The size of
    1151     * {@link #allObjects} will always be less than or equal to {@link
    1152     * #_maxActive}. Map keys are pooled objects, values are the PooledObject
    1153     * wrappers used internally by the pool.
    1154     */
    1155    private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =
    1156        new ConcurrentHashMap<>();
    1157    /*
    1158     * The combined count of the currently created objects and those in the
    1159     * process of being created. Under load, it may exceed {@link #_maxActive}
    1160     * if multiple threads try and create a new object at the same time but
    1161     * {@link #create()} will ensure that there are never more than
    1162     * {@link #_maxActive} objects created at any one time.
    1163     */
    1164    private final AtomicLong createCount = new AtomicLong(0);
    1165    private long makeObjectCount = 0;
    1166    private final Object makeObjectCountLock = new Object();
    1167    private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
    1168
    1169    // JMX specific attributes
    1170    private static final String ONAME_BASE =
    1171        "org.apache.commons.pool2:type=GenericObjectPool,name=";
    1172
    1173    // Additional configuration properties for abandoned object tracking
    1174    private volatile AbandonedConfig abandonedConfig = null;
    1175
    1176    @Override
    1177    protected void toStringAppendFields(final StringBuilder builder) {
    1178        super.toStringAppendFields(builder);
    1179        builder.append(", factoryType=");
    1180        builder.append(factoryType);
    1181        builder.append(", maxIdle=");
    1182        builder.append(maxIdle);
    1183        builder.append(", minIdle=");
    1184        builder.append(minIdle);
    1185        builder.append(", factory=");
    1186        builder.append(factory);
    1187        builder.append(", allObjects=");
    1188        builder.append(allObjects);
    1189        builder.append(", createCount=");
    1190        builder.append(createCount);
    1191        builder.append(", idleObjects=");
    1192        builder.append(idleObjects);
    1193        builder.append(", abandonedConfig=");
    1194        builder.append(abandonedConfig);
    1195    }
    1196
    1197}