/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.pool.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TimerTask;
import java.util.TreeMap;

import org.apache.commons.pool.BaseKeyedObjectPool;
import org.apache.commons.pool.KeyedObjectPool;
import org.apache.commons.pool.KeyedPoolableObjectFactory;
import org.apache.commons.pool.PoolUtils;

A configurable KeyedObjectPool implementation.

When coupled with the appropriate KeyedPoolableObjectFactory, GenericKeyedObjectPool provides robust pooling functionality for keyed objects. A GenericKeyedObjectPool can be viewed as a map of pools, keyed on the (unique) key values provided to the preparePool, addObject or borrowObject methods. Each time a new key value is provided to one of these methods, a new pool is created under the given key to be managed by the containing GenericKeyedObjectPool.

A GenericKeyedObjectPool provides a number of configurable parameters:

Optionally, one may configure the pool to examine and possibly evict objects as they sit idle in the pool and to ensure that a minimum number of idle objects is maintained for each key. This is performed by an "idle object eviction" thread, which runs asynchronously. Caution should be used when configuring this optional feature. Eviction runs contend with client threads for access to objects in the pool, so if they run too frequently performance issues may result. The idle object eviction thread may be configured using the following attributes:

  • timeBetweenEvictionRunsMillis indicates how long the eviction thread should sleep before "runs" of examining idle objects. When non-positive, no eviction thread will be launched. The default setting for this parameter is -1 (i.e., by default, idle object eviction is disabled).
  • minEvictableIdleTimeMillis specifies the minimum amount of time that an object may sit idle in the pool before it is eligible for eviction due to idle time. When non-positive, no object will be dropped from the pool due to idle time alone. This setting has no effect unless timeBetweenEvictionRunsMillis > 0. The default setting for this parameter is 30 minutes.
  • testWhileIdle indicates whether or not idle objects should be validated using the factory's validateObject method during idle object eviction runs. Objects that fail to validate will be dropped from the pool. This setting has no effect unless timeBetweenEvictionRunsMillis > 0. The default setting for this parameter is false.
  • minIdle sets a target value for the minimum number of idle objects (per key) that should always be available. If this parameter is set to a positive number and timeBetweenEvictionRunsMillis > 0, each time the idle object eviction thread runs, it will try to create enough idle instances so that there will be minIdle idle instances available under each key. This parameter is also used by preparePool if true is provided as that method's populateImmediately parameter. The default setting for this parameter is 0.

The pools can be configured to behave as LIFO queues with respect to idle objects - always returning the most recently used object from the pool, or as FIFO queues, where borrowObject always returns the oldest object in the idle object pool.

  • Lifo determines whether or not the pools return idle objects in last-in-first-out order. The default setting for this parameter is true.

GenericKeyedObjectPool is not usable without a KeyedPoolableObjectFactory. A non-null factory must be provided either as a constructor argument or via a call to setFactory before the pool is used.

Implementation note: To prevent possible deadlocks, care has been taken to ensure that no call to a factory method will occur within a synchronization block. See POOL-125 and DBCP-44 for more information.

Author:Rodney Waldhoff, Dirk Verbeeck, Sandy McArthur
Type parameters:
  • <K> – the type of keys in this pool
  • <V> – the type of objects held in this pool
See Also:
Version:$Revision: 1222396 $ $Date: 2011-12-22 14:02:25 -0500 (Thu, 22 Dec 2011) $
Since:Pool 1.0
/** * A configurable <code>KeyedObjectPool</code> implementation. * <p> * When coupled with the appropriate {@link KeyedPoolableObjectFactory}, * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map * of pools, keyed on the (unique) key values provided to the * {@link #preparePool preparePool}, {@link #addObject addObject} or * {@link #borrowObject borrowObject} methods. Each time a new key value is * provided to one of these methods, a new pool is created under the given key * to be managed by the containing <code>GenericKeyedObjectPool.</code> * </p> * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable * parameters:</p> * <ul> * <li> * {@link #setMaxActive maxActive} controls the maximum number of objects * (per key) that can allocated by the pool (checked out to client threads, * or idle in the pool) at one time. When non-positive, there is no limit * to the number of objects per key. When {@link #setMaxActive maxActive} is * reached, the keyed pool is said to be exhausted. The default setting for * this parameter is 8. * </li> * <li> * {@link #setMaxTotal maxTotal} sets a global limit on the number of objects * that can be in circulation (active or idle) within the combined set of * pools. When non-positive, there is no limit to the total number of * objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded, * all keyed pools are exhausted. When <code>maxTotal</code> is set to a * positive value and {@link #borrowObject borrowObject} is invoked * when at the limit with no idle instances available, an attempt is made to * create room by clearing the oldest 15% of the elements from the keyed * pools. The default setting for this parameter is -1 (no limit). * </li> * <li> * {@link #setMaxIdle maxIdle} controls the maximum number of objects that can * sit idle in the pool (per key) at any time. When negative, there * is no limit to the number of objects that may be idle per key. The * default setting for this parameter is 8. * </li> * <li> * {@link #setWhenExhaustedAction whenExhaustedAction} specifies the * behavior of the {@link #borrowObject borrowObject} method when a keyed * pool is exhausted: * <ul> * <li> * When {@link #setWhenExhaustedAction whenExhaustedAction} is * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw * a {@link NoSuchElementException} * </li> * <li> * When {@link #setWhenExhaustedAction whenExhaustedAction} is * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new * object and return it (essentially making {@link #setMaxActive maxActive} * meaningless.) * </li> * <li> * When {@link #setWhenExhaustedAction whenExhaustedAction} * is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block * (invoke {@link Object#wait() wait} until a new or idle object is available. * If a positive {@link #setMaxWait maxWait} * value is supplied, the {@link #borrowObject borrowObject} will block for at * most that many milliseconds, after which a {@link NoSuchElementException} * will be thrown. If {@link #setMaxWait maxWait} is non-positive, * the {@link #borrowObject borrowObject} method will block indefinitely. * </li> * </ul> * The default <code>whenExhaustedAction</code> setting is * {@link #WHEN_EXHAUSTED_BLOCK}. * </li> * <li> * When {@link #setTestOnBorrow testOnBorrow} is set, the pool will * attempt to validate each object before it is returned from the * {@link #borrowObject borrowObject} method. (Using the provided factory's * {@link KeyedPoolableObjectFactory#validateObject validateObject} method.) * Objects that fail to validate will be dropped from the pool, and a * different object will be borrowed. The default setting for this parameter * is <code>false.</code> * </li> * <li> * When {@link #setTestOnReturn testOnReturn} is set, the pool will * attempt to validate each object before it is returned to the pool in the * {@link #returnObject returnObject} method. (Using the provided factory's * {@link KeyedPoolableObjectFactory#validateObject validateObject} * method.) Objects that fail to validate will be dropped from the pool. * The default setting for this parameter is <code>false.</code> * </li> * </ul> * <p> * Optionally, one may configure the pool to examine and possibly evict objects * as they sit idle in the pool and to ensure that a minimum number of idle * objects is maintained for each key. This is performed by an * "idle object eviction" thread, which runs asynchronously. Caution should be * used when configuring this optional feature. Eviction runs contend with client * threads for access to objects in the pool, so if they run too frequently * performance issues may result. The idle object eviction thread may be * configured using the following attributes: * <ul> * <li> * {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis} * indicates how long the eviction thread should sleep before "runs" of examining * idle objects. When non-positive, no eviction thread will be launched. The * default setting for this parameter is -1 (i.e., by default, idle object * eviction is disabled). * </li> * <li> * {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis} * specifies the minimum amount of time that an object may sit idle in the * pool before it is eligible for eviction due to idle time. When * non-positive, no object will be dropped from the pool due to idle time * alone. This setting has no effect unless * <code>timeBetweenEvictionRunsMillis > 0.</code> The default setting * for this parameter is 30 minutes. * </li> * <li> * {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle * objects should be validated using the factory's * {@link KeyedPoolableObjectFactory#validateObject validateObject} method * during idle object eviction runs. Objects that fail to validate will be * dropped from the pool. This setting has no effect unless * <code>timeBetweenEvictionRunsMillis > 0.</code> The default setting * for this parameter is <code>false.</code> * </li> * <li> * {@link #setMinIdle minIdle} sets a target value for the minimum number of * idle objects (per key) that should always be available. If this parameter * is set to a positive number and * <code>timeBetweenEvictionRunsMillis > 0,</code> each time the idle object * eviction thread runs, it will try to create enough idle instances so that * there will be <code>minIdle</code> idle instances available under each * key. This parameter is also used by {@link #preparePool preparePool} * if <code>true</code> is provided as that method's * <code>populateImmediately</code> parameter. The default setting for this * parameter is 0. * </li> * </ul> * <p> * The pools can be configured to behave as LIFO queues with respect to idle * objects - always returning the most recently used object from the pool, * or as FIFO queues, where borrowObject always returns the oldest object * in the idle object pool. * <ul> * <li> * {@link #setLifo <i>Lifo</i>} * determines whether or not the pools return idle objects in * last-in-first-out order. The default setting for this parameter is * <code>true.</code> * </li> * </ul> * <p> * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}. A * non-<code>null</code> factory must be provided either as a constructor argument * or via a call to {@link #setFactory setFactory} before the pool is used. * </p> * <p> * Implementation note: To prevent possible deadlocks, care has been taken to * ensure that no call to a factory method will occur within a synchronization * block. See POOL-125 and DBCP-44 for more information. * </p> * * @param <K> the type of keys in this pool * @param <V> the type of objects held in this pool * * @see GenericObjectPool * @author Rodney Waldhoff * @author Dirk Verbeeck * @author Sandy McArthur * @version $Revision: 1222396 $ $Date: 2011-12-22 14:02:25 -0500 (Thu, 22 Dec 2011) $ * @since Pool 1.0 */
public class GenericKeyedObjectPool<K, V> extends BaseKeyedObjectPool<K, V> implements KeyedObjectPool<K, V> { //--- public constants -------------------------------------------
A "when exhausted action" type indicating that when the pool is exhausted (i.e., the maximum number of active objects has been reached), the borrowObject method should fail, throwing a NoSuchElementException.
See Also:
/** * A "when exhausted action" type indicating that when the pool is * exhausted (i.e., the maximum number of active objects has * been reached), the {@link #borrowObject} * method should fail, throwing a {@link NoSuchElementException}. * @see #WHEN_EXHAUSTED_BLOCK * @see #WHEN_EXHAUSTED_GROW * @see #setWhenExhaustedAction */
public static final byte WHEN_EXHAUSTED_FAIL = 0;
A "when exhausted action" type indicating that when the pool is exhausted (i.e., the maximum number of active objects has been reached), the borrowObject method should block until a new object is available, or the maximum wait time has been reached.
See Also:
/** * A "when exhausted action" type indicating that when the pool * is exhausted (i.e., the maximum number * of active objects has been reached), the {@link #borrowObject} * method should block until a new object is available, or the * {@link #getMaxWait maximum wait time} has been reached. * @see #WHEN_EXHAUSTED_FAIL * @see #WHEN_EXHAUSTED_GROW * @see #setMaxWait * @see #getMaxWait * @see #setWhenExhaustedAction */
public static final byte WHEN_EXHAUSTED_BLOCK = 1;
A "when exhausted action" type indicating that when the pool is exhausted (i.e., the maximum number of active objects has been reached), the borrowObject method should simply create a new object anyway.
See Also:
/** * A "when exhausted action" type indicating that when the pool is * exhausted (i.e., the maximum number * of active objects has been reached), the {@link #borrowObject} * method should simply create a new object anyway. * @see #WHEN_EXHAUSTED_FAIL * @see #WHEN_EXHAUSTED_GROW * @see #setWhenExhaustedAction */
public static final byte WHEN_EXHAUSTED_GROW = 2;
The default cap on the number of idle instances (per key) in the pool.
See Also:
/** * The default cap on the number of idle instances (per key) in the pool. * @see #getMaxIdle * @see #setMaxIdle */
public static final int DEFAULT_MAX_IDLE = 8;
The default cap on the total number of active instances (per key) from the pool.
See Also:
/** * The default cap on the total number of active instances (per key) * from the pool. * @see #getMaxActive * @see #setMaxActive */
public static final int DEFAULT_MAX_ACTIVE = 8;
The default cap on the the overall maximum number of objects that can exist at one time.
See Also:
/** * The default cap on the the overall maximum number of objects that can * exist at one time. * @see #getMaxTotal * @see #setMaxTotal */
public static final int DEFAULT_MAX_TOTAL = -1;
The default "when exhausted action" for the pool.
See Also:
/** * The default "when exhausted action" for the pool. * @see #WHEN_EXHAUSTED_BLOCK * @see #WHEN_EXHAUSTED_FAIL * @see #WHEN_EXHAUSTED_GROW * @see #setWhenExhaustedAction */
public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
The default maximum amount of time (in milliseconds) the borrowObject method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK.
See Also:
/** * The default maximum amount of time (in milliseconds) the * {@link #borrowObject} method should block before throwing * an exception when the pool is exhausted and the * {@link #getWhenExhaustedAction "when exhausted" action} is * {@link #WHEN_EXHAUSTED_BLOCK}. * @see #getMaxWait * @see #setMaxWait */
public static final long DEFAULT_MAX_WAIT = -1L;
The default "test on borrow" value.
See Also:
/** * The default "test on borrow" value. * @see #getTestOnBorrow * @see #setTestOnBorrow */
public static final boolean DEFAULT_TEST_ON_BORROW = false;
The default "test on return" value.
See Also:
/** * The default "test on return" value. * @see #getTestOnReturn * @see #setTestOnReturn */
public static final boolean DEFAULT_TEST_ON_RETURN = false;
The default "test while idle" value.
See Also:
/** * The default "test while idle" value. * @see #getTestWhileIdle * @see #setTestWhileIdle * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
The default "time between eviction runs" value.
See Also:
/** * The default "time between eviction runs" value. * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
The default number of objects to examine per run in the idle object evictor.
See Also:
/** * The default number of objects to examine per run in the * idle object evictor. * @see #getNumTestsPerEvictionRun * @see #setNumTestsPerEvictionRun * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
The default value for getMinEvictableIdleTimeMillis.
See Also:
/** * The default value for {@link #getMinEvictableIdleTimeMillis}. * @see #getMinEvictableIdleTimeMillis * @see #setMinEvictableIdleTimeMillis */
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
The default minimum level of idle objects in the pool.
See Also:
Since:Pool 1.3
/** * The default minimum level of idle objects in the pool. * @since Pool 1.3 * @see #setMinIdle * @see #getMinIdle */
public static final int DEFAULT_MIN_IDLE = 0;
The default LIFO status. True means that borrowObject returns the most recently used ("last in") idle object in a pool (if there are idle instances available). False means that pools behave as FIFO queues - objects are taken from idle object pools in the order that they are returned.
See Also:
  • setLifo
/** * The default LIFO status. True means that borrowObject returns the * most recently used ("last in") idle object in a pool (if there are * idle instances available). False means that pools behave as FIFO * queues - objects are taken from idle object pools in the order that * they are returned. * @see #setLifo */
public static final boolean DEFAULT_LIFO = true; //--- constructors -----------------------------------------------
Create a new GenericKeyedObjectPool with no factory.
See Also:
/** * Create a new <code>GenericKeyedObjectPool</code> with no factory. * * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory) * @see #setFactory(KeyedPoolableObjectFactory) */
public GenericKeyedObjectPool() { this(null, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy * objects if not <code>null</code> */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory) { this(factory, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • config – a non-null Config describing the configuration
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, GenericKeyedObjectPool.Config config) { this(factory, config.maxActive, config.whenExhaustedAction, config.maxWait, config.maxIdle, config.maxTotal, config.minIdle, config.testOnBorrow, config.testOnReturn, config.timeBetweenEvictionRunsMillis, config.numTestsPerEvictionRun, config.minEvictableIdleTimeMillis, config.testWhileIdle, config.lifo); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive) { this(factory,maxActive, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait) { this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) { this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time * (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) { this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see getMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time * (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) { this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, testOnBorrow, testOnReturn, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
  • timeBetweenEvictionRunsMillis – the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis)
  • numTestsPerEvictionRun – the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun)
  • minEvictableIdleTimeMillis – the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis)
  • testWhileIdle – whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time * (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted * (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis}) * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction * thread (if any) (see {@link #setNumTestsPerEvictionRun}) * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis}) * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any * (see {@link #setTestWhileIdle}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) { this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed from me at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
  • maxTotal – the maximum number of objects that can exists at one time (see setMaxTotal)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
  • timeBetweenEvictionRunsMillis – the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis)
  • numTestsPerEvictionRun – the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun)
  • minEvictableIdleTimeMillis – the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis)
  • testWhileIdle – whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle)
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed from me at one time * (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis}) * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction * thread (if any) (see {@link #setNumTestsPerEvictionRun}) * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool * before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis}) * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any * (see {@link #setTestWhileIdle}) */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) { this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
  • maxTotal – the maximum number of objects that can exists at one time (see setMaxTotal)
  • minIdle – the minimum number of idle objects to have in the pool at any one time (see setMinIdle)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
  • timeBetweenEvictionRunsMillis – the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis)
  • numTestsPerEvictionRun – the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun)
  • minEvictableIdleTimeMillis – the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis)
  • testWhileIdle – whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle)
Since:Pool 1.3
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed at one time (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal}) * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle * objects * for eviction (see {@link #setTimeBetweenEvictionRunsMillis}) * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction * thread (if any) (see {@link #setNumTestsPerEvictionRun}) * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis}) * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any * (see {@link #setTestWhileIdle}) * @since Pool 1.3 */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) { this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, DEFAULT_LIFO); }
Create a new GenericKeyedObjectPool using the specified values.
Params:
  • factory – the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
  • maxActive – the maximum number of objects that can be borrowed at one time (see setMaxActive)
  • whenExhaustedAction – the action to take when the pool is exhausted (see setWhenExhaustedAction)
  • maxWait – the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait)
  • maxIdle – the maximum number of idle objects in my pool (see setMaxIdle)
  • maxTotal – the maximum number of objects that can exists at one time (see setMaxTotal)
  • minIdle – the minimum number of idle objects to have in the pool at any one time (see setMinIdle)
  • testOnBorrow – whether or not to validate objects before they are returned by the borrowObject method (see setTestOnBorrow)
  • testOnReturn – whether or not to validate objects after they are returned to the returnObject method (see setTestOnReturn)
  • timeBetweenEvictionRunsMillis – the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis)
  • numTestsPerEvictionRun – the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun)
  • minEvictableIdleTimeMillis – the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis)
  • testWhileIdle – whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle)
  • lifo – whether or not the pools behave as LIFO (last in first out) queues (see setLifo)
Since:Pool 1.4
/** * Create a new <code>GenericKeyedObjectPool</code> using the specified values. * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects * if not <code>null</code> * @param maxActive the maximum number of objects that can be borrowed at one time * (see {@link #setMaxActive}) * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction}) * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait}) * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle}) * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal}) * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle}) * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} * method (see {@link #setTestOnBorrow}) * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} * method (see {@link #setTestOnReturn}) * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis}) * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction * thread (if any) (see {@link #setNumTestsPerEvictionRun}) * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis}) * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any * (see {@link #setTestWhileIdle}) * @param lifo whether or not the pools behave as LIFO (last in first out) queues (see {@link #setLifo}) * @since Pool 1.4 */
public GenericKeyedObjectPool(KeyedPoolableObjectFactory<K, V> factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, boolean lifo) { _factory = factory; _maxActive = maxActive; _lifo = lifo; switch (whenExhaustedAction) { case WHEN_EXHAUSTED_BLOCK: case WHEN_EXHAUSTED_FAIL: case WHEN_EXHAUSTED_GROW: _whenExhaustedAction = whenExhaustedAction; break; default: throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized."); } _maxWait = maxWait; _maxIdle = maxIdle; _maxTotal = maxTotal; _minIdle = minIdle; _testOnBorrow = testOnBorrow; _testOnReturn = testOnReturn; _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; _numTestsPerEvictionRun = numTestsPerEvictionRun; _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; _testWhileIdle = testWhileIdle; _poolMap = new HashMap<K, ObjectQueue>(); _poolList = new CursorableLinkedList<K>(); startEvictor(_timeBetweenEvictionRunsMillis); } //--- public methods --------------------------------------------- //--- configuration methods --------------------------------------
Returns the cap on the number of object instances allocated by the pool (checked out or idle), per key. A negative value indicates no limit.
See Also:
Returns:the cap on the number of active instances per key.
/** * Returns the cap on the number of object instances allocated by the pool * (checked out or idle), per key. * A negative value indicates no limit. * * @return the cap on the number of active instances per key. * @see #setMaxActive */
public synchronized int getMaxActive() { return _maxActive; }
Sets the cap on the number of object instances managed by the pool per key.
Params:
  • maxActive – The cap on the number of object instances per key. Use a negative value for no limit.
See Also:
/** * Sets the cap on the number of object instances managed by the pool per key. * @param maxActive The cap on the number of object instances per key. * Use a negative value for no limit. * * @see #getMaxActive */
public void setMaxActive(int maxActive) { synchronized(this) { _maxActive = maxActive; } allocate(); }
Returns the overall maximum number of objects (across pools) that can exist at one time. A negative value indicates no limit.
See Also:
Returns:the maximum number of instances in circulation at one time.
/** * Returns the overall maximum number of objects (across pools) that can * exist at one time. A negative value indicates no limit. * @return the maximum number of instances in circulation at one time. * @see #setMaxTotal */
public synchronized int getMaxTotal() { return _maxTotal; }
Sets the cap on the total number of instances from all pools combined. When maxTotal is set to a positive value and borrowObject is invoked when at the limit with no idle instances available, an attempt is made to create room by clearing the oldest 15% of the elements from the keyed pools.
Params:
  • maxTotal – The cap on the total number of instances across pools. Use a negative value for no limit.
See Also:
/** * Sets the cap on the total number of instances from all pools combined. * When <code>maxTotal</code> is set to a * positive value and {@link #borrowObject borrowObject} is invoked * when at the limit with no idle instances available, an attempt is made to * create room by clearing the oldest 15% of the elements from the keyed * pools. * * @param maxTotal The cap on the total number of instances across pools. * Use a negative value for no limit. * @see #getMaxTotal */
public void setMaxTotal(int maxTotal) { synchronized(this) { _maxTotal = maxTotal; } allocate(); }
Returns the action to take when the borrowObject method is invoked when the pool is exhausted (the maximum number of "active" objects has been reached).
See Also:
Returns:one of GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK, GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_FAIL or GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_GROW
/** * Returns the action to take when the {@link #borrowObject} method * is invoked when the pool is exhausted (the maximum number * of "active" objects has been reached). * * @return one of {@link #WHEN_EXHAUSTED_BLOCK}, * {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW} * @see #setWhenExhaustedAction */
public synchronized byte getWhenExhaustedAction() { return _whenExhaustedAction; }
Sets the action to take when the borrowObject method is invoked when the pool is exhausted (the maximum number of "active" objects has been reached).
Params:
See Also:
/** * Sets the action to take when the {@link #borrowObject} method * is invoked when the pool is exhausted (the maximum number * of "active" objects has been reached). * * @param whenExhaustedAction the action code, which must be one of * {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL}, * or {@link #WHEN_EXHAUSTED_GROW} * @see #getWhenExhaustedAction */
public void setWhenExhaustedAction(byte whenExhaustedAction) { synchronized(this) { switch(whenExhaustedAction) { case WHEN_EXHAUSTED_BLOCK: case WHEN_EXHAUSTED_FAIL: case WHEN_EXHAUSTED_GROW: _whenExhaustedAction = whenExhaustedAction; break; default: throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized."); } } allocate(); }
Returns the maximum amount of time (in milliseconds) the borrowObject method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject method may block indefinitely.
See Also:
Returns:the maximum number of milliseconds borrowObject will block.
/** * Returns the maximum amount of time (in milliseconds) the * {@link #borrowObject} method should block before throwing * an exception when the pool is exhausted and the * {@link #setWhenExhaustedAction "when exhausted" action} is * {@link #WHEN_EXHAUSTED_BLOCK}. * * When less than or equal to 0, the {@link #borrowObject} method * may block indefinitely. * * @return the maximum number of milliseconds borrowObject will block. * @see #setMaxWait * @see #setWhenExhaustedAction * @see #WHEN_EXHAUSTED_BLOCK */
public synchronized long getMaxWait() { return _maxWait; }
Sets the maximum amount of time (in milliseconds) the borrowObject method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject method may block indefinitely.
Params:
  • maxWait – the maximum number of milliseconds borrowObject will block or negative for indefinitely.
See Also:
/** * Sets the maximum amount of time (in milliseconds) the * {@link #borrowObject} method should block before throwing * an exception when the pool is exhausted and the * {@link #setWhenExhaustedAction "when exhausted" action} is * {@link #WHEN_EXHAUSTED_BLOCK}. * * When less than or equal to 0, the {@link #borrowObject} method * may block indefinitely. * * @param maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely. * @see #getMaxWait * @see #setWhenExhaustedAction * @see #WHEN_EXHAUSTED_BLOCK */
public void setMaxWait(long maxWait) { synchronized(this) { _maxWait = maxWait; } allocate(); }
Returns the cap on the number of "idle" instances per key.
See Also:
Returns:the maximum number of "idle" instances that can be held in a given keyed pool.
/** * Returns the cap on the number of "idle" instances per key. * @return the maximum number of "idle" instances that can be held * in a given keyed pool. * @see #setMaxIdle */
public synchronized int getMaxIdle() { return _maxIdle; }
Sets the cap on the number of "idle" instances in the pool. If maxIdle is set too low on heavily loaded systems it is possible you will see objects being destroyed and almost immediately new objects being created. This is a result of the active threads momentarily returning objects faster than they are requesting them them, causing the number of idle objects to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good starting point.
Params:
  • maxIdle – the maximum number of "idle" instances that can be held in a given keyed pool. Use a negative value for no limit.
See Also:
/** * Sets the cap on the number of "idle" instances in the pool. * If maxIdle is set too low on heavily loaded systems it is possible you * will see objects being destroyed and almost immediately new objects * being created. This is a result of the active threads momentarily * returning objects faster than they are requesting them them, causing the * number of idle objects to rise above maxIdle. The best value for maxIdle * for heavily loaded system will vary but the default is a good starting * point. * @param maxIdle the maximum number of "idle" instances that can be held * in a given keyed pool. Use a negative value for no limit. * @see #getMaxIdle * @see #DEFAULT_MAX_IDLE */
public void setMaxIdle(int maxIdle) { synchronized(this) { _maxIdle = maxIdle; } allocate(); }
Sets the minimum number of idle objects to maintain in each of the keyed pools. This setting has no effect unless timeBetweenEvictionRunsMillis > 0 and attempts to ensure that each pool has the required minimum number of instances are only made during idle object eviction runs.
Params:
  • poolSize – - The minimum size of the each keyed pool
See Also:
Since:Pool 1.3
/** * Sets the minimum number of idle objects to maintain in each of the keyed * pools. This setting has no effect unless * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure * that each pool has the required minimum number of instances are only * made during idle object eviction runs. * @param poolSize - The minimum size of the each keyed pool * @since Pool 1.3 * @see #getMinIdle * @see #setTimeBetweenEvictionRunsMillis */
public void setMinIdle(int poolSize) { _minIdle = poolSize; }
Returns the minimum number of idle objects to maintain in each of the keyed pools. This setting has no effect unless timeBetweenEvictionRunsMillis > 0 and attempts to ensure that each pool has the required minimum number of instances are only made during idle object eviction runs.
See Also:
Returns:minimum size of the each keyed pool
Since:Pool 1.3
/** * Returns the minimum number of idle objects to maintain in each of the keyed * pools. This setting has no effect unless * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure * that each pool has the required minimum number of instances are only * made during idle object eviction runs. * @return minimum size of the each keyed pool * @since Pool 1.3 * @see #setTimeBetweenEvictionRunsMillis */
public int getMinIdle() { return _minIdle; }
When true, objects will be validated before being returned by the borrowObject method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.
See Also:
Returns:true if objects are validated before being borrowed.
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned by the {@link #borrowObject} * method. If the object fails to validate, * it will be dropped from the pool, and we will attempt * to borrow another. * * @return <code>true</code> if objects are validated before being borrowed. * @see #setTestOnBorrow */
public boolean getTestOnBorrow() { return _testOnBorrow; }
When true, objects will be validated before being returned by the borrowObject method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.
Params:
  • testOnBorrow – whether object should be validated before being returned by borrowObject.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned by the {@link #borrowObject} * method. If the object fails to validate, * it will be dropped from the pool, and we will attempt * to borrow another. * * @param testOnBorrow whether object should be validated before being returned by borrowObject. * @see #getTestOnBorrow */
public void setTestOnBorrow(boolean testOnBorrow) { _testOnBorrow = testOnBorrow; }
When true, objects will be validated before being returned to the pool within the returnObject.
See Also:
Returns:true when objects will be validated before being returned.
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned to the pool within the * {@link #returnObject}. * * @return <code>true</code> when objects will be validated before being returned. * @see #setTestOnReturn */
public boolean getTestOnReturn() { return _testOnReturn; }
When true, objects will be validated before being returned to the pool within the returnObject.
Params:
  • testOnReturn – true so objects will be validated before being returned.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned to the pool within the * {@link #returnObject}. * * @param testOnReturn <code>true</code> so objects will be validated before being returned. * @see #getTestOnReturn */
public void setTestOnReturn(boolean testOnReturn) { _testOnReturn = testOnReturn; }
Returns the number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.
See Also:
Returns:milliseconds to sleep between evictor runs.
/** * Returns the number of milliseconds to sleep between runs of the * idle object evictor thread. * When non-positive, no idle object evictor thread will be * run. * * @return milliseconds to sleep between evictor runs. * @see #setTimeBetweenEvictionRunsMillis */
public synchronized long getTimeBetweenEvictionRunsMillis() { return _timeBetweenEvictionRunsMillis; }
Sets the number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.
Params:
  • timeBetweenEvictionRunsMillis – milliseconds to sleep between evictor runs.
See Also:
/** * Sets the number of milliseconds to sleep between runs of the * idle object evictor thread. * When non-positive, no idle object evictor thread will be * run. * * @param timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs. * @see #getTimeBetweenEvictionRunsMillis */
public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; startEvictor(_timeBetweenEvictionRunsMillis); }
Returns the max number of objects to examine during each run of the idle object evictor thread (if any).
See Also:
Returns:number of objects to examine each eviction run.
/** * Returns the max number of objects to examine during each run of the * idle object evictor thread (if any). * * @return number of objects to examine each eviction run. * @see #setNumTestsPerEvictionRun * @see #setTimeBetweenEvictionRunsMillis */
public synchronized int getNumTestsPerEvictionRun() { return _numTestsPerEvictionRun; }
Sets the max number of objects to examine during each run of the idle object evictor thread (if any).

When a negative value is supplied, ceil(getNumIdle())/abs(getNumTestsPerEvictionRun) tests will be run. I.e., when the value is -n, roughly one nth of the idle objects will be tested per run. When the value is positive, the number of tests actually performed in each run will be the minimum of this value and the number of instances idle in the pools.

Params:
  • numTestsPerEvictionRun – number of objects to examine each eviction run.
See Also:
/** * Sets the max number of objects to examine during each run of the * idle object evictor thread (if any). * <p> * When a negative value is supplied, * <code>ceil({@link #getNumIdle()})/abs({@link #getNumTestsPerEvictionRun})</code> * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the * idle objects will be tested per run. When the value is positive, the number of tests * actually performed in each run will be the minimum of this value and the number of instances * idle in the pools. * * @param numTestsPerEvictionRun number of objects to examine each eviction run. * @see #setNumTestsPerEvictionRun * @see #setTimeBetweenEvictionRunsMillis */
public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { _numTestsPerEvictionRun = numTestsPerEvictionRun; }
Returns the minimum amount of time an object may sit idle in the pool before it is eligible for eviction by the idle object evictor (if any).
See Also:
Returns:minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
/** * Returns the minimum amount of time an object may sit idle in the pool * before it is eligible for eviction by the idle object evictor * (if any). * * @return minimum amount of time an object may sit idle in the pool before it is eligible for eviction. * @see #setMinEvictableIdleTimeMillis * @see #setTimeBetweenEvictionRunsMillis */
public synchronized long getMinEvictableIdleTimeMillis() { return _minEvictableIdleTimeMillis; }
Sets the minimum amount of time an object may sit idle in the pool before it is eligible for eviction by the idle object evictor (if any). When non-positive, no objects will be evicted from the pool due to idle time alone.
Params:
  • minEvictableIdleTimeMillis – minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
See Also:
/** * Sets the minimum amount of time an object may sit idle in the pool * before it is eligible for eviction by the idle object evictor * (if any). * When non-positive, no objects will be evicted from the pool * due to idle time alone. * * @param minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before * it is eligible for eviction. * @see #getMinEvictableIdleTimeMillis * @see #setTimeBetweenEvictionRunsMillis */
public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; }
When true, objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool.
See Also:
Returns:true when objects are validated when borrowed.
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * by the idle object evictor (if any). If an object * fails to validate, it will be dropped from the pool. * * @return <code>true</code> when objects are validated when borrowed. * @see #setTestWhileIdle * @see #setTimeBetweenEvictionRunsMillis */
public synchronized boolean getTestWhileIdle() { return _testWhileIdle; }
When true, objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool.
Params:
  • testWhileIdle – true so objects are validated when borrowed.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * by the idle object evictor (if any). If an object * fails to validate, it will be dropped from the pool. * * @param testWhileIdle <code>true</code> so objects are validated when borrowed. * @see #getTestWhileIdle * @see #setTimeBetweenEvictionRunsMillis */
public synchronized void setTestWhileIdle(boolean testWhileIdle) { _testWhileIdle = testWhileIdle; }
Sets the configuration.
Params:
  • conf – the new configuration to use.
See Also:
/** * Sets the configuration. * @param conf the new configuration to use. * @see GenericKeyedObjectPool.Config */
public synchronized void setConfig(GenericKeyedObjectPool.Config conf) { setMaxIdle(conf.maxIdle); setMaxActive(conf.maxActive); setMaxTotal(conf.maxTotal); setMinIdle(conf.minIdle); setMaxWait(conf.maxWait); setWhenExhaustedAction(conf.whenExhaustedAction); setTestOnBorrow(conf.testOnBorrow); setTestOnReturn(conf.testOnReturn); setTestWhileIdle(conf.testWhileIdle); setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun); setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis); setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis); }
Whether or not the idle object pools act as LIFO queues. True means that borrowObject returns the most recently used ("last in") idle object in a pool (if there are idle instances available). False means that the pools behave as FIFO queues - objects are taken from idle object pools in the order that they are returned.
Returns:true if the pools are configured to act as LIFO queues
Since:1.4
/** * Whether or not the idle object pools act as LIFO queues. True means * that borrowObject returns the most recently used ("last in") idle object * in a pool (if there are idle instances available). False means that * the pools behave as FIFO queues - objects are taken from idle object * pools in the order that they are returned. * * @return <code>true</code> if the pools are configured to act as LIFO queues * @since 1.4 */
public synchronized boolean getLifo() { return _lifo; }
Sets the LIFO property of the pools. True means that borrowObject returns the most recently used ("last in") idle object in a pool (if there are idle instances available). False means that the pools behave as FIFO queues - objects are taken from idle object pools in the order that they are returned.
Params:
  • lifo – the new value for the lifo property
Since:1.4
/** * Sets the LIFO property of the pools. True means that borrowObject returns * the most recently used ("last in") idle object in a pool (if there are * idle instances available). False means that the pools behave as FIFO * queues - objects are taken from idle object pools in the order that * they are returned. * * @param lifo the new value for the lifo property * @since 1.4 */
public synchronized void setLifo(boolean lifo) { this._lifo = lifo; } //-- ObjectPool methods ------------------------------------------

Borrows an object from the keyed pool associated with the given key.

If there is an idle instance available in the pool associated with the given key, then either the most-recently returned (if lifo == true) or "oldest" (lifo == false) instance sitting idle in the pool will be activated and returned. If activation fails, or testOnBorrow is set to true and validation fails, the instance is destroyed and the next available instance is examined. This continues until either a valid instance is returned or there are no more idle instances available.

If there are no idle instances available in the pool associated with the given key, behavior depends on the maxActive, maxTotal, and (if applicable) whenExhaustedAction and maxWait properties. If the number of instances checked out from the pool under the given key is less than maxActive and the total number of instances in circulation (under all keys) is less than maxTotal, a new instance is created, activated and (if applicable) validated and returned to the caller.

If the associated keyed pool is exhausted (no available idle instances and no capacity to create new ones), this method will either block (GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK), throw a NoSuchElementException (GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_FAIL), or grow (GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_GROW - ignoring maxActive, maxTotal properties). The length of time that this method will block when whenExhaustedAction == WHEN_EXHAUSTED_BLOCK is determined by the maxWait property.

When the pool is exhausted, multiple calling threads may be simultaneously blocked waiting for instances to become available. As of pool 1.5, a "fairness" algorithm has been implemented to ensure that threads receive available instances in request arrival order.

Params:
  • key – pool key
Throws:
Returns:object instance from the keyed pool
/** * <p>Borrows an object from the keyed pool associated with the given key.</p> * * <p>If there is an idle instance available in the pool associated with the given key, then * either the most-recently returned (if {@link #getLifo() lifo} == true) or "oldest" (lifo == false) * instance sitting idle in the pool will be activated and returned. If activation fails, or * {@link #getTestOnBorrow() testOnBorrow} is set to true and validation fails, the instance is destroyed and the * next available instance is examined. This continues until either a valid instance is returned or there * are no more idle instances available.</p> * * <p>If there are no idle instances available in the pool associated with the given key, behavior * depends on the {@link #getMaxActive() maxActive}, {@link #getMaxTotal() maxTotal}, and (if applicable) * {@link #getWhenExhaustedAction() whenExhaustedAction} and {@link #getMaxWait() maxWait} properties. If the * number of instances checked out from the pool under the given key is less than <code>maxActive</code> and * the total number of instances in circulation (under all keys) is less than <code>maxTotal</code>, a new instance * is created, activated and (if applicable) validated and returned to the caller.</p> * * <p>If the associated keyed pool is exhausted (no available idle instances and no capacity to create new ones), * this method will either block ({@link #WHEN_EXHAUSTED_BLOCK}), throw a <code>NoSuchElementException</code> * ({@link #WHEN_EXHAUSTED_FAIL}), or grow ({@link #WHEN_EXHAUSTED_GROW} - ignoring maxActive, maxTotal properties). * The length of time that this method will block when <code>whenExhaustedAction == WHEN_EXHAUSTED_BLOCK</code> * is determined by the {@link #getMaxWait() maxWait} property.</p> * * <p>When the pool is exhausted, multiple calling threads may be simultaneously blocked waiting for instances * to become available. As of pool 1.5, a "fairness" algorithm has been implemented to ensure that threads receive * available instances in request arrival order.</p> * * @param key pool key * @return object instance from the keyed pool * @throws NoSuchElementException if a keyed object instance cannot be returned. */
@Override public V borrowObject(K key) throws Exception { long starttime = System.currentTimeMillis(); Latch<K, V> latch = new Latch<K, V>(key); byte whenExhaustedAction; long maxWait; synchronized (this) { // Get local copy of current config. Can't sync when used later as // it can result in a deadlock. Has the added advantage that config // is consistent for entire method execution whenExhaustedAction = _whenExhaustedAction; maxWait = _maxWait; // Add this request to the queue _allocationQueue.add(latch); } // Work the allocation queue, allocating idle instances and // instance creation permits in request arrival order allocate(); for(;;) { synchronized (this) { assertOpen(); } // If no object was allocated if (null == latch.getPair()) { // Check to see if we were allowed to create one if (latch.mayCreate()) { // allow new object to be created } else { // the pool is exhausted switch(whenExhaustedAction) { case WHEN_EXHAUSTED_GROW: // allow new object to be created synchronized (this) { // Make sure another thread didn't allocate us an object // or permit a new object to be created if (latch.getPair() == null && !latch.mayCreate()) { _allocationQueue.remove(latch); latch.getPool().incrementInternalProcessingCount(); } } break; case WHEN_EXHAUSTED_FAIL: synchronized (this) { // Make sure allocate hasn't already assigned an object // in a different thread or permitted a new object to be created if (latch.getPair() != null || latch.mayCreate()) { break; } _allocationQueue.remove(latch); } throw new NoSuchElementException("Pool exhausted"); case WHEN_EXHAUSTED_BLOCK: try { synchronized (latch) { // Before we wait, make sure another thread didn't allocate us an object // or permit a new object to be created if (latch.getPair() == null && !latch.mayCreate()) { if (maxWait <= 0) { latch.wait(); } else { // this code may be executed again after a notify then continue cycle // so, need to calculate the amount of time to wait final long elapsed = (System.currentTimeMillis() - starttime); final long waitTime = maxWait - elapsed; if (waitTime > 0) { latch.wait(waitTime); } } } else { break; } } // see if we were awakened by a closing pool if(isClosed() == true) { throw new IllegalStateException("Pool closed"); } } catch(InterruptedException e) { boolean doAllocate = false; synchronized (this) { // Need to handle the all three possibilities if (latch.getPair() == null && !latch.mayCreate()) { // Case 1: latch still in allocation queue // Remove latch from the allocation queue _allocationQueue.remove(latch); } else if (latch.getPair() == null && latch.mayCreate()) { // Case 2: latch has been given permission to create // a new object latch.getPool().decrementInternalProcessingCount(); doAllocate = true; } else { // Case 3: An object has been allocated latch.getPool().decrementInternalProcessingCount(); latch.getPool().incrementActiveCount(); returnObject(latch.getkey(), latch.getPair().getValue()); } } if (doAllocate) { allocate(); } Thread.currentThread().interrupt(); throw e; } if (maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) { synchronized (this) { // Make sure allocate hasn't already assigned an object // in a different thread or permitted a new object to be created if (latch.getPair() == null && !latch.mayCreate()) { _allocationQueue.remove(latch); } else { break; } } throw new NoSuchElementException("Timeout waiting for idle object"); } else { continue; // keep looping } default: throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized."); } } } boolean newlyCreated = false; if (null == latch.getPair()) { try { V obj = _factory.makeObject(key); latch.setPair(new ObjectTimestampPair<V>(obj)); newlyCreated = true; } finally { if (!newlyCreated) { // object cannot be created synchronized (this) { latch.getPool().decrementInternalProcessingCount(); // No need to reset latch - about to throw exception } allocate(); } } } // activate & validate the object try { _factory.activateObject(key, latch.getPair().value); if (_testOnBorrow && !_factory.validateObject(key, latch.getPair().value)) { throw new Exception("ValidateObject failed"); } synchronized (this) { latch.getPool().decrementInternalProcessingCount(); latch.getPool().incrementActiveCount(); } return latch.getPair().value; } catch (Throwable e) { PoolUtils.checkRethrow(e); // object cannot be activated or is invalid try { _factory.destroyObject(key, latch.getPair().value); } catch (Throwable e2) { PoolUtils.checkRethrow(e2); // cannot destroy broken object } synchronized (this) { latch.getPool().decrementInternalProcessingCount(); if (!newlyCreated) { latch.reset(); _allocationQueue.add(0, latch); } } allocate(); if (newlyCreated) { throw new NoSuchElementException( "Could not create a validated object, cause: " + e.getMessage()); } else { continue; // keep looping } } } }
Allocate available instances to latches in the allocation queue. Then set _mayCreate to true for as many additional latches remaining in queue as _maxActive allows for each key. This method MUST NOT be called from inside a sync block.
/** * Allocate available instances to latches in the allocation queue. Then * set _mayCreate to true for as many additional latches remaining in queue * as _maxActive allows for each key. This method <b>MUST NOT</b> be called * from inside a sync block. */
private void allocate() { boolean clearOldest = false; synchronized (this) { if (isClosed()) return; Iterator<Latch<K, V>> allocationQueueIter = _allocationQueue.iterator(); while (allocationQueueIter.hasNext()) { // First use any objects in the pool to clear the queue Latch<K, V> latch = allocationQueueIter.next(); ObjectQueue pool = (_poolMap.get(latch.getkey())); if (null == pool) { pool = new ObjectQueue(); _poolMap.put(latch.getkey(), pool); _poolList.add(latch.getkey()); } latch.setPool(pool); if (!pool.queue.isEmpty()) { allocationQueueIter.remove(); latch.setPair( pool.queue.removeFirst()); pool.incrementInternalProcessingCount(); _totalIdle--; synchronized (latch) { latch.notify(); } // Next item in queue continue; } // If there is a totalMaxActive and we are at the limit then // we have to make room if ((_maxTotal > 0) && (_totalActive + _totalIdle + _totalInternalProcessing >= _maxTotal)) { clearOldest = true; break; } // Second utilise any spare capacity to create new objects if ((_maxActive < 0 || pool.activeCount + pool.internalProcessingCount < _maxActive) && (_maxTotal < 0 || _totalActive + _totalIdle + _totalInternalProcessing < _maxTotal)) { // allow new object to be created allocationQueueIter.remove(); latch.setMayCreate(true); pool.incrementInternalProcessingCount(); synchronized (latch) { latch.notify(); } // Next item in queue continue; } // If there is no per-key limit and we reach this point we // must have allocated all the objects we possibly can and there // is no point looking at the rest of the allocation queue if (_maxActive < 0) { break; } } } if (clearOldest) { /* Clear oldest calls factory methods so it must be called from * outside the sync block. * It also needs to be outside the sync block as it calls * allocate(). If called inside the sync block, the call to * allocate() would be able to enter the sync block (since the * thread already has the lock) which may have unexpected, * unpleasant results. */ clearOldest(); } }
Clears any objects sitting idle in the pool by removing them from the idle instance pool and then invoking the configured PoolableObjectFactory's KeyedPoolableObjectFactory.destroyObject(Object, Object) method on each idle instance.

Implementation notes:

  • This method does not destroy or effect in any way instances that are checked out when it is invoked.
  • Invoking this method does not prevent objects being returned to the idle instance pool, even during its execution. It locks the pool only during instance removal. Additional instances may be returned while removed items are being destroyed.
  • Exceptions encountered destroying idle instances are swallowed.

/** * Clears any objects sitting idle in the pool by removing them from the * idle instance pool and then invoking the configured PoolableObjectFactory's * {@link KeyedPoolableObjectFactory#destroyObject(Object, Object)} method on * each idle instance. * * <p> Implementation notes: * <ul><li>This method does not destroy or effect in any way instances that are * checked out when it is invoked.</li> * <li>Invoking this method does not prevent objects being * returned to the idle instance pool, even during its execution. It locks * the pool only during instance removal. Additional instances may be returned * while removed items are being destroyed.</li> * <li>Exceptions encountered destroying idle instances are swallowed.</li></ul></p> */
@Override public void clear() { Map<K, List<ObjectTimestampPair<V>>> toDestroy = new HashMap<K, List<ObjectTimestampPair<V>>>(); synchronized (this) { for (Iterator<K> it = _poolMap.keySet().iterator(); it.hasNext();) { K key = it.next(); ObjectQueue pool = _poolMap.get(key); // Copy objects to new list so pool.queue can be cleared inside // the sync List<ObjectTimestampPair<V>> objects = new ArrayList<ObjectTimestampPair<V>>(); objects.addAll(pool.queue); toDestroy.put(key, objects); it.remove(); _poolList.remove(key); _totalIdle = _totalIdle - pool.queue.size(); _totalInternalProcessing = _totalInternalProcessing + pool.queue.size(); pool.queue.clear(); } } destroy(toDestroy, _factory); }
Clears oldest 15% of objects in pool. The method sorts the objects into a TreeMap and then iterates the first 15% for removal.
Since:Pool 1.3
/** * Clears oldest 15% of objects in pool. The method sorts the * objects into a TreeMap and then iterates the first 15% for removal. * * @since Pool 1.3 */
public void clearOldest() { // Map of objects to destroy my key final Map<K, List<ObjectTimestampPair<V>>> toDestroy = new HashMap<K, List<ObjectTimestampPair<V>>>(); // build sorted map of idle objects final Map<ObjectTimestampPair<V>, K> map = new TreeMap<ObjectTimestampPair<V>, K>(); synchronized (this) { for (Iterator<K> keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) { final K key = keyiter.next(); final List<ObjectTimestampPair<V>> list = _poolMap.get(key).queue; for (Iterator<ObjectTimestampPair<V>> it = list.iterator(); it.hasNext();) { // each item into the map uses the objectimestamppair object // as the key. It then gets sorted based on the timstamp field // each value in the map is the parent list it belongs in. map.put(it.next(), key); } } // Now iterate created map and kill the first 15% plus one to account for zero Set<Entry<ObjectTimestampPair<V>, K>> setPairKeys = map.entrySet(); int itemsToRemove = ((int) (map.size() * 0.15)) + 1; Iterator<Entry<ObjectTimestampPair<V>, K>> iter = setPairKeys.iterator(); while (iter.hasNext() && itemsToRemove > 0) { Entry<ObjectTimestampPair<V>, K> entry = iter.next(); // kind of backwards on naming. In the map, each key is the objecttimestamppair // because it has the ordering with the timestamp value. Each value that the // key references is the key of the list it belongs to. K key = entry.getValue(); ObjectTimestampPair<V> pairTimeStamp = entry.getKey(); ObjectQueue objectQueue = _poolMap.get(key); final List<ObjectTimestampPair<V>> list = objectQueue.queue; list.remove(pairTimeStamp); if (toDestroy.containsKey(key)) { toDestroy.get(key).add(pairTimeStamp); } else { List<ObjectTimestampPair<V>> listForKey = new ArrayList<ObjectTimestampPair<V>>(); listForKey.add(pairTimeStamp); toDestroy.put(key, listForKey); } objectQueue.incrementInternalProcessingCount(); _totalIdle--; itemsToRemove--; } } destroy(toDestroy, _factory); }
Clears the specified pool, removing all pooled instances corresponding to the given key.
Params:
  • key – the key to clear
/** * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>. * * @param key the key to clear */
@Override public void clear(K key) { Map<K, List<ObjectTimestampPair<V>>> toDestroy = new HashMap<K , List<ObjectTimestampPair<V>>>(); final ObjectQueue pool; synchronized (this) { pool = _poolMap.remove(key); if (pool == null) { return; } else { _poolList.remove(key); } // Copy objects to new list so pool.queue can be cleared inside // the sync List<ObjectTimestampPair<V>> objects = new ArrayList<ObjectTimestampPair<V>>(); objects.addAll(pool.queue); toDestroy.put(key, objects); _totalIdle = _totalIdle - pool.queue.size(); _totalInternalProcessing = _totalInternalProcessing + pool.queue.size(); pool.queue.clear(); } destroy(toDestroy, _factory); }
Assuming Map>, destroy all ObjectTimestampPair.value using the supplied factory.
Params:
  • m – Map containing keyed pools to clear
  • factory – KeyedPoolableObjectFactory used to destroy the objects
/** * Assuming Map<Object,Collection<ObjectTimestampPair>>, destroy all * ObjectTimestampPair.value using the supplied factory. * * @param m Map containing keyed pools to clear * @param factory KeyedPoolableObjectFactory used to destroy the objects */
private void destroy(Map<K, List<ObjectTimestampPair<V>>> m, KeyedPoolableObjectFactory<K, V> factory) { for (Iterator<Entry<K, List<ObjectTimestampPair<V>>>> entries = m.entrySet().iterator(); entries.hasNext();) { Entry<K, List<ObjectTimestampPair<V>>> entry = entries.next(); K key = entry.getKey(); List<ObjectTimestampPair<V>> c = entry.getValue(); for (Iterator<ObjectTimestampPair<V>> it = c.iterator(); it.hasNext();) { try { factory.destroyObject( key,it.next().value); } catch(Exception e) { // ignore error, keep destroying the rest } finally { synchronized(this) { ObjectQueue objectQueue = _poolMap.get(key); if (objectQueue != null) { objectQueue.decrementInternalProcessingCount(); if (objectQueue.internalProcessingCount == 0 && objectQueue.activeCount == 0 && objectQueue.queue.isEmpty()) { _poolMap.remove(key); _poolList.remove(key); } } else { _totalInternalProcessing--; } } allocate(); } } } }
Returns the total number of instances current borrowed from this pool but not yet returned.
Returns:the total number of instances currently borrowed from this pool
/** * Returns the total number of instances current borrowed from this pool but not yet returned. * * @return the total number of instances currently borrowed from this pool */
@Override public synchronized int getNumActive() { return _totalActive; }
Returns the total number of instances currently idle in this pool.
Returns:the total number of instances currently idle in this pool
/** * Returns the total number of instances currently idle in this pool. * * @return the total number of instances currently idle in this pool */
@Override public synchronized int getNumIdle() { return _totalIdle; }
Returns the number of instances currently borrowed from but not yet returned to the pool corresponding to the given key.
Params:
  • key – the key to query
Returns:the number of instances corresponding to the given key currently borrowed in this pool
/** * Returns the number of instances currently borrowed from but not yet returned * to the pool corresponding to the given <code>key</code>. * * @param key the key to query * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool */
@Override public synchronized int getNumActive(Object key) { final ObjectQueue pool = (_poolMap.get(key)); return pool != null ? pool.activeCount : 0; }
Returns the number of instances corresponding to the given key currently idle in this pool.
Params:
  • key – the key to query
Returns:the number of instances corresponding to the given key currently idle in this pool
/** * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool. * * @param key the key to query * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool */
@Override public synchronized int getNumIdle(Object key) { final ObjectQueue pool = (_poolMap.get(key)); return pool != null ? pool.queue.size() : 0; }

Returns an object to a keyed pool.

For the pool to function correctly, the object instance must have been borrowed from the pool (under the same key) and not yet returned. Repeated returnObject calls on the same object/key pair (with no borrowObject calls in between) will result in multiple references to the object in the idle instance pool.

If maxIdle is set to a positive value and the number of idle instances under the given key has reached this value, the returning instance is destroyed.

If testOnReturn == true, the returning instance is validated before being returned to the idle instance pool under the given key. In this case, if validation fails, the instance is destroyed.

Params:
  • key – pool key
  • obj – instance to return to the keyed pool
Throws:
/** * <p>Returns an object to a keyed pool.</p> * * <p>For the pool to function correctly, the object instance <strong>must</strong> have been borrowed * from the pool (under the same key) and not yet returned. Repeated <code>returnObject</code> calls on * the same object/key pair (with no <code>borrowObject</code> calls in between) will result in multiple * references to the object in the idle instance pool.</p> * * <p>If {@link #getMaxIdle() maxIdle} is set to a positive value and the number of idle instances under the given * key has reached this value, the returning instance is destroyed.</p> * * <p>If {@link #getTestOnReturn() testOnReturn} == true, the returning instance is validated before being returned * to the idle instance pool under the given key. In this case, if validation fails, the instance is destroyed.</p> * * @param key pool key * @param obj instance to return to the keyed pool * @throws Exception */
@Override public void returnObject(K key, V obj) throws Exception { try { addObjectToPool(key, obj, true); } catch (Exception e) { if (_factory != null) { try { _factory.destroyObject(key, obj); } catch (Exception e2) { // swallowed } // TODO: Correctness here depends on control in addObjectToPool. // These two methods should be refactored, removing the // "behavior flag", decrementNumActive, from addObjectToPool. ObjectQueue pool = (_poolMap.get(key)); if (pool != null) { synchronized(this) { pool.decrementActiveCount(); if (pool.queue.isEmpty() && pool.activeCount == 0 && pool.internalProcessingCount == 0) { _poolMap.remove(key); _poolList.remove(key); } } allocate(); } } } }

Adds an object to the keyed pool.

Validates the object if testOnReturn == true and passivates it before returning it to the pool. if validation or passivation fails, or maxIdle is set and there is no room in the pool, the instance is destroyed.

Calls allocate() on successful completion

Params:
  • key – pool key
  • obj – instance to add to the keyed pool
  • decrementNumActive – whether or not to decrement the active count associated with the keyed pool
Throws:
/** * <p>Adds an object to the keyed pool.</p> * * <p>Validates the object if testOnReturn == true and passivates it before returning it to the pool. * if validation or passivation fails, or maxIdle is set and there is no room in the pool, the instance * is destroyed.</p> * * <p>Calls {@link #allocate()} on successful completion</p> * * @param key pool key * @param obj instance to add to the keyed pool * @param decrementNumActive whether or not to decrement the active count associated with the keyed pool * @throws Exception */
private void addObjectToPool(K key, V obj, boolean decrementNumActive) throws Exception { // if we need to validate this object, do so boolean success = true; // whether or not this object passed validation if (_testOnReturn && !_factory.validateObject(key, obj)) { success = false; } else { _factory.passivateObject(key, obj); } boolean shouldDestroy = !success; ObjectQueue pool; // Add instance to pool if there is room and it has passed validation // (if testOnreturn is set) boolean doAllocate = false; synchronized (this) { // grab the pool (list) of objects associated with the given key pool = _poolMap.get(key); // if it doesn't exist, create it if (null == pool) { pool = new ObjectQueue(); _poolMap.put(key, pool); _poolList.add(key); } if (isClosed()) { shouldDestroy = true; } else { // if there's no space in the pool, flag the object for destruction // else if we passivated successfully, return it to the pool if (_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) { shouldDestroy = true; } else if (success) { // borrowObject always takes the first element from the queue, // so for LIFO, push on top, FIFO add to end if (_lifo) { pool.queue.addFirst(new ObjectTimestampPair<V>(obj)); } else { pool.queue.addLast(new ObjectTimestampPair<V>(obj)); } _totalIdle++; if (decrementNumActive) { pool.decrementActiveCount(); } doAllocate = true; } } } if (doAllocate) { allocate(); } // Destroy the instance if necessary if (shouldDestroy) { try { _factory.destroyObject(key, obj); } catch(Exception e) { // ignored? } // Decrement active count *after* destroy if applicable if (decrementNumActive) { synchronized(this) { pool.decrementActiveCount(); if (pool.queue.isEmpty() && pool.activeCount == 0 && pool.internalProcessingCount == 0) { _poolMap.remove(key); _poolList.remove(key); } } allocate(); } } }
{@inheritDoc}

Activation of this method decrements the active count associated with the given keyed pool and attempts to destroy obj.

Params:
  • key – pool key
  • obj – instance to invalidate
Throws:
  • Exception – if an exception occurs destroying the object
/** * {@inheritDoc} * <p>Activation of this method decrements the active count associated with the given keyed pool * and attempts to destroy <code>obj.</code></p> * * @param key pool key * @param obj instance to invalidate * @throws Exception if an exception occurs destroying the object */
@Override public void invalidateObject(K key, V obj) throws Exception { try { _factory.destroyObject(key, obj); } finally { synchronized (this) { ObjectQueue pool = (_poolMap.get(key)); if (null == pool) { pool = new ObjectQueue(); _poolMap.put(key, pool); _poolList.add(key); } pool.decrementActiveCount(); } allocate(); // _totalActive has changed } }
Create an object using the factory, passivate it, and then place it in the idle object pool. addObject is useful for "pre-loading" a pool with idle objects.
Params:
  • key – the key a new instance should be added to
Throws:
/** * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory}, * passivate it, and then place it in the idle object pool. * <code>addObject</code> is useful for "pre-loading" a pool with idle objects. * * @param key the key a new instance should be added to * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails. * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been * called on this pool. */
@Override public void addObject(K key) throws Exception { assertOpen(); if (_factory == null) { throw new IllegalStateException("Cannot add objects without a factory."); } V obj = _factory.makeObject(key); try { assertOpen(); addObjectToPool(key, obj, false); } catch (IllegalStateException ex) { // Pool closed try { _factory.destroyObject(key, obj); } catch (Exception ex2) { // swallow } throw ex; } }
Registers a key for pool control. If populateImmediately is true and minIdle > 0, the pool under the given key will be populated immediately with minIdle idle instances.
Params:
  • key – - The key to register for pool control.
  • populateImmediately – - If this is true, the pool will be populated immediately.
Since:Pool 1.3
/** * Registers a key for pool control. * * If <code>populateImmediately</code> is <code>true</code> and * <code>minIdle > 0,</code> the pool under the given key will be * populated immediately with <code>minIdle</code> idle instances. * * @param key - The key to register for pool control. * @param populateImmediately - If this is <code>true</code>, the pool * will be populated immediately. * @since Pool 1.3 */
public synchronized void preparePool(K key, boolean populateImmediately) { ObjectQueue pool = (_poolMap.get(key)); if (null == pool) { pool = new ObjectQueue(); _poolMap.put(key,pool); _poolList.add(key); } if (populateImmediately) { try { // Create the pooled objects ensureMinIdle(key); } catch (Exception e) { //Do nothing } } }

Closes the keyed object pool. Once the pool is closed, borrowObject(Object) will fail with IllegalStateException, but returnObject(Object, Object) and invalidateObject(Object, Object) will continue to work, with returned objects destroyed on return.

Destroys idle instances in the pool by invoking clear().

Throws:
/** * <p>Closes the keyed object pool. Once the pool is closed, {@link #borrowObject(Object)} * will fail with IllegalStateException, but {@link #returnObject(Object, Object)} and * {@link #invalidateObject(Object, Object)} will continue to work, with returned objects * destroyed on return.</p> * * <p>Destroys idle instances in the pool by invoking {@link #clear()}.</p> * * @throws Exception */
@Override public void close() throws Exception { super.close(); synchronized (this) { clear(); if (null != _evictionCursor) { _evictionCursor.close(); _evictionCursor = null; } if (null != _evictionKeyCursor) { _evictionKeyCursor.close(); _evictionKeyCursor = null; } startEvictor(-1L); while(_allocationQueue.size() > 0) { Latch<K, V> l = _allocationQueue.removeFirst(); synchronized (l) { // notify the waiting thread l.notify(); } } } }

Sets the keyed poolable object factory associated with this pool.

If this method is called when objects are checked out of any of the keyed pools, an IllegalStateException is thrown. Calling this method also has the side effect of destroying any idle instances in existing keyed pools, using the original factory.

Params:
  • factory – KeyedPoolableObjectFactory to use when creating keyed object pool instances
Throws:
  • IllegalStateException – if there are active (checked out) instances associated with this keyed object pool
Deprecated:to be removed in version 2.0
/** * <p>Sets the keyed poolable object factory associated with this pool.</p> * * <p>If this method is called when objects are checked out of any of the keyed pools, * an IllegalStateException is thrown. Calling this method also has the side effect of * destroying any idle instances in existing keyed pools, using the original factory.</p> * * @param factory KeyedPoolableObjectFactory to use when creating keyed object pool instances * @throws IllegalStateException if there are active (checked out) instances associated with this keyed object pool * @deprecated to be removed in version 2.0 */
@Deprecated @Override public void setFactory(KeyedPoolableObjectFactory<K, V> factory) throws IllegalStateException { Map<K, List<ObjectTimestampPair<V>>> toDestroy = new HashMap<K, List<ObjectTimestampPair<V>>>(); final KeyedPoolableObjectFactory<K, V> oldFactory = _factory; synchronized (this) { assertOpen(); if (0 < getNumActive()) { throw new IllegalStateException("Objects are already active"); } else { for (Iterator<K> it = _poolMap.keySet().iterator(); it.hasNext();) { K key = it.next(); ObjectQueue pool = _poolMap.get(key); if (pool != null) { // Copy objects to new list so pool.queue can be cleared // inside the sync List<ObjectTimestampPair<V>> objects = new ArrayList<ObjectTimestampPair<V>>(); objects.addAll(pool.queue); toDestroy.put(key, objects); it.remove(); _poolList.remove(key); _totalIdle = _totalIdle - pool.queue.size(); _totalInternalProcessing = _totalInternalProcessing + pool.queue.size(); pool.queue.clear(); } } _factory = factory; } } destroy(toDestroy, oldFactory); }

Perform numTests idle object eviction tests, evicting examined objects that meet the criteria for eviction. If testWhileIdle is true, examined objects are validated when visited (and removed if invalid); otherwise only objects that have been idle for more than minEvicableIdletimeMillis are removed.

Successive activations of this method examine objects in keyed pools in sequence, cycling through the keys and examining objects in oldest-to-youngest order within the keyed pools.

Throws:
  • Exception – when there is a problem evicting idle objects.
/** * <p>Perform <code>numTests</code> idle object eviction tests, evicting * examined objects that meet the criteria for eviction. If * <code>testWhileIdle</code> is true, examined objects are validated * when visited (and removed if invalid); otherwise only objects that * have been idle for more than <code>minEvicableIdletimeMillis</code> * are removed.</p> * * <p>Successive activations of this method examine objects in keyed pools * in sequence, cycling through the keys and examining objects in * oldest-to-youngest order within the keyed pools.</p> * * @throws Exception when there is a problem evicting idle objects. */
public void evict() throws Exception { K key = null; boolean testWhileIdle; long minEvictableIdleTimeMillis; synchronized (this) { // Get local copy of current config. Can't sync when used later as // it can result in a deadlock. Has the added advantage that config // is consistent for entire method execution testWhileIdle = _testWhileIdle; minEvictableIdleTimeMillis = _minEvictableIdleTimeMillis; // Initialize key to last key value if (_evictionKeyCursor != null && _evictionKeyCursor._lastReturned != null) { key = _evictionKeyCursor._lastReturned.value(); } } for (int i=0, m=getNumTests(); i<m; i++) { final ObjectTimestampPair<V> pair; synchronized (this) { // make sure pool map is not empty; otherwise do nothing if (_poolMap == null || _poolMap.size() == 0) { continue; } // if we don't have a key cursor, then create one if (null == _evictionKeyCursor) { resetEvictionKeyCursor(); key = null; } // if we don't have an object cursor, create one if (null == _evictionCursor) { // if the _evictionKeyCursor has a next value, use this key if (_evictionKeyCursor.hasNext()) { key = _evictionKeyCursor.next(); resetEvictionObjectCursor(key); } else { // Reset the key cursor and try again resetEvictionKeyCursor(); if (_evictionKeyCursor != null) { if (_evictionKeyCursor.hasNext()) { key = _evictionKeyCursor.next(); resetEvictionObjectCursor(key); } } } } if (_evictionCursor == null) { continue; // should never happen; do nothing } // If eviction cursor is exhausted, try to move // to the next key and reset if ((_lifo && !_evictionCursor.hasPrevious()) || (!_lifo && !_evictionCursor.hasNext())) { if (_evictionKeyCursor != null) { if (_evictionKeyCursor.hasNext()) { key = _evictionKeyCursor.next(); resetEvictionObjectCursor(key); } else { // Need to reset Key cursor resetEvictionKeyCursor(); if (_evictionKeyCursor != null) { if (_evictionKeyCursor.hasNext()) { key = _evictionKeyCursor.next(); resetEvictionObjectCursor(key); } } } } } if ((_lifo && !_evictionCursor.hasPrevious()) || (!_lifo && !_evictionCursor.hasNext())) { continue; // reset failed, do nothing } // if LIFO and the _evictionCursor has a previous object, // or FIFO and _evictionCursor has a next object, test it pair = _lifo ? _evictionCursor.previous() : _evictionCursor.next(); _evictionCursor.remove(); ObjectQueue objectQueue = _poolMap.get(key); objectQueue.incrementInternalProcessingCount(); _totalIdle--; } boolean removeObject=false; if ((minEvictableIdleTimeMillis > 0) && (System.currentTimeMillis() - pair.tstamp > minEvictableIdleTimeMillis)) { removeObject=true; } if (testWhileIdle && removeObject == false) { boolean active = false; try { _factory.activateObject(key,pair.value); active = true; } catch(Exception e) { removeObject=true; } if (active) { if (!_factory.validateObject(key,pair.value)) { removeObject=true; } else { try { _factory.passivateObject(key,pair.value); } catch(Exception e) { removeObject=true; } } } } if (removeObject) { try { _factory.destroyObject(key, pair.value); } catch(Exception e) { // ignored } } synchronized (this) { ObjectQueue objectQueue = _poolMap.get(key); objectQueue.decrementInternalProcessingCount(); if (removeObject) { if (objectQueue.queue.isEmpty() && objectQueue.activeCount == 0 && objectQueue.internalProcessingCount == 0) { _poolMap.remove(key); _poolList.remove(key); } } else { _evictionCursor.add(pair); _totalIdle++; if (_lifo) { // Skip over the element we just added back _evictionCursor.previous(); } } } } allocate(); }
Resets the eviction key cursor and closes any associated eviction object cursor
/** * Resets the eviction key cursor and closes any * associated eviction object cursor */
private void resetEvictionKeyCursor() { if (_evictionKeyCursor != null) { _evictionKeyCursor.close(); } _evictionKeyCursor = _poolList.cursor(); if (null != _evictionCursor) { _evictionCursor.close(); _evictionCursor = null; } }
Resets the eviction object cursor for the given key
Params:
  • key – eviction key
/** * Resets the eviction object cursor for the given key * * @param key eviction key */
private void resetEvictionObjectCursor(Object key) { if (_evictionCursor != null) { _evictionCursor.close(); } if (_poolMap == null) { return; } ObjectQueue pool = _poolMap.get(key); if (pool != null) { CursorableLinkedList<ObjectTimestampPair<V>> queue = pool.queue; _evictionCursor = queue.cursor(_lifo ? queue.size() : 0); } }
Iterates through all the known keys and creates any necessary objects to maintain the minimum level of pooled objects.
Throws:
  • Exception – If there was an error whilst creating the pooled objects.
See Also:
/** * Iterates through all the known keys and creates any necessary objects to maintain * the minimum level of pooled objects. * @see #getMinIdle * @see #setMinIdle * @throws Exception If there was an error whilst creating the pooled objects. */
@SuppressWarnings("unchecked") private void ensureMinIdle() throws Exception { //Check if should sustain the pool if (_minIdle > 0) { Object[] keysCopy; synchronized(this) { // Get the current set of keys keysCopy = _poolMap.keySet().toArray(); } // Loop through all elements in _poolList // Find out the total number of max active and max idle for that class // If the number is less than the minIdle, do creation loop to boost numbers for (int i=0; i < keysCopy.length; i++) { //Get the next key to process ensureMinIdle((K)keysCopy[i]); } } }
Re-creates any needed objects to maintain the minimum levels of pooled objects for the specified key. This method uses calculateDeficit to calculate the number of objects to be created. calculateDeficit can be overridden to provide a different method of calculating the number of objects to be created.
Params:
  • key – The key to process
Throws:
  • Exception – If there was an error whilst creating the pooled objects
/** * Re-creates any needed objects to maintain the minimum levels of * pooled objects for the specified key. * * This method uses {@link #calculateDeficit} to calculate the number * of objects to be created. {@link #calculateDeficit} can be overridden to * provide a different method of calculating the number of objects to be * created. * @param key The key to process * @throws Exception If there was an error whilst creating the pooled objects */
private void ensureMinIdle(K key) throws Exception { // Calculate current pool objects ObjectQueue pool; synchronized(this) { pool = (_poolMap.get(key)); } if (pool == null) { return; } // this method isn't synchronized so the // calculateDeficit is done at the beginning // as a loop limit and a second time inside the loop // to stop when another thread already returned the // needed objects int objectDeficit = calculateDeficit(pool, false); for (int i = 0; i < objectDeficit && calculateDeficit(pool, true) > 0; i++) { try { addObject(key); } finally { synchronized (this) { pool.decrementInternalProcessingCount(); } allocate(); } } } //--- non-public methods ----------------------------------------
Start the eviction thread or service, or when delay is non-positive, stop it if it is already running.
Params:
  • delay – milliseconds between evictor runs.
/** * Start the eviction thread or service, or when * <code>delay</code> is non-positive, stop it * if it is already running. * * @param delay milliseconds between evictor runs. */
protected synchronized void startEvictor(long delay) { if (null != _evictor) { EvictionTimer.cancel(_evictor); _evictor = null; } if (delay > 0) { _evictor = new Evictor(); EvictionTimer.schedule(_evictor, delay, delay); } }
Returns pool info including getNumActive(), getNumIdle() and currently defined keys.
Returns:string containing debug information
/** * Returns pool info including {@link #getNumActive()}, {@link #getNumIdle()} * and currently defined keys. * * @return string containing debug information */
synchronized String debugInfo() { StringBuffer buf = new StringBuffer(); buf.append("Active: ").append(getNumActive()).append("\n"); buf.append("Idle: ").append(getNumIdle()).append("\n"); Iterator<K> it = _poolMap.keySet().iterator(); while (it.hasNext()) { K key = it.next(); buf.append("\t").append(key).append(" ").append(_poolMap.get(key)).append("\n"); } return buf.toString(); }
Returns the number of tests to be performed in an Evictor run, based on the current values of _numTestsPerEvictionRun and _totalIdle.
See Also:
  • setNumTestsPerEvictionRun
Returns:the number of tests for the Evictor to run
/** * Returns the number of tests to be performed in an Evictor run, * based on the current values of <code>_numTestsPerEvictionRun</code> * and <code>_totalIdle</code>. * * @see #setNumTestsPerEvictionRun * @return the number of tests for the Evictor to run */
private synchronized int getNumTests() { if (_numTestsPerEvictionRun >= 0) { return Math.min(_numTestsPerEvictionRun, _totalIdle); } else { return(int)(Math.ceil(_totalIdle/Math.abs((double)_numTestsPerEvictionRun))); } }
This returns the number of objects to create during the pool sustain cycle. This will ensure that the minimum number of idle instances is maintained without going past the maxActive value.
Params:
  • pool – the ObjectPool to calculate the deficit for
  • incrementInternal – - Should the count of objects currently under some form of internal processing be incremented?
Returns:The number of objects to be created
/** * This returns the number of objects to create during the pool * sustain cycle. This will ensure that the minimum number of idle * instances is maintained without going past the maxActive value. * * @param pool the ObjectPool to calculate the deficit for * @param incrementInternal - Should the count of objects currently under * some form of internal processing be * incremented? * @return The number of objects to be created */
private synchronized int calculateDeficit(ObjectQueue pool, boolean incrementInternal) { int objectDefecit = 0; //Calculate no of objects needed to be created, in order to have //the number of pooled objects < maxActive(); objectDefecit = getMinIdle() - pool.queue.size(); if (getMaxActive() > 0) { int growLimit = Math.max(0, getMaxActive() - pool.activeCount - pool.queue.size() - pool.internalProcessingCount); objectDefecit = Math.min(objectDefecit, growLimit); } // Take the maxTotal limit into account if (getMaxTotal() > 0) { int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle() - _totalInternalProcessing); objectDefecit = Math.min(objectDefecit, growLimit); } if (incrementInternal && objectDefecit > 0) { pool.incrementInternalProcessingCount(); } return objectDefecit; } //--- inner classes ----------------------------------------------
A "struct" that keeps additional information about the actual queue of pooled objects.
/** * A "struct" that keeps additional information about the actual queue of pooled objects. */
private class ObjectQueue {
Number of instances checked out to clients from this queue
/** Number of instances checked out to clients from this queue */
private int activeCount = 0;
Idle instance queue
/** Idle instance queue */
private final CursorableLinkedList<ObjectTimestampPair<V>> queue = new CursorableLinkedList<ObjectTimestampPair<V>>();
Number of instances in process of being created
/** Number of instances in process of being created */
private int internalProcessingCount = 0;
Increment the active count for this queue
/** Increment the active count for this queue */
void incrementActiveCount() { synchronized (GenericKeyedObjectPool.this) { _totalActive++; } activeCount++; }
Decrement the active count for this queue
/** Decrement the active count for this queue */
void decrementActiveCount() { synchronized (GenericKeyedObjectPool.this) { _totalActive--; } if (activeCount > 0) { activeCount--; } }
Record the fact that one more instance is queued for creation
/** Record the fact that one more instance is queued for creation */
void incrementInternalProcessingCount() { synchronized (GenericKeyedObjectPool.this) { _totalInternalProcessing++; } internalProcessingCount++; }
Decrement the number of instances in process of being created
/** Decrement the number of instances in process of being created */
void decrementInternalProcessingCount() { synchronized (GenericKeyedObjectPool.this) { _totalInternalProcessing--; } internalProcessingCount--; } }
A simple "struct" encapsulating an object instance and a timestamp. Implements Comparable, objects are sorted from old to new. This is also used by GenericObjectPool.
/** * A simple "struct" encapsulating an object instance and a timestamp. * * Implements Comparable, objects are sorted from old to new. * * This is also used by {@link GenericObjectPool}. */
static class ObjectTimestampPair<T> implements Comparable<T> { //CHECKSTYLE: stop VisibilityModifier
Object instance
Deprecated:this field will be made private and final in version 2.0
/** * Object instance * @deprecated this field will be made private and final in version 2.0 */
@Deprecated T value;
timestamp
Deprecated:this field will be made private and final in version 2.0
/** * timestamp * @deprecated this field will be made private and final in version 2.0 */
@Deprecated long tstamp; //CHECKSTYLE: resume VisibilityModifier
Create a new ObjectTimestampPair using the given object and the current system time.
Params:
  • val – object instance
/** * Create a new ObjectTimestampPair using the given object and the current system time. * @param val object instance */
ObjectTimestampPair(T val) { this(val, System.currentTimeMillis()); }
Create a new ObjectTimeStampPair using the given object and timestamp value.
Params:
  • val – object instance
  • time – long representation of timestamp
/** * Create a new ObjectTimeStampPair using the given object and timestamp value. * @param val object instance * @param time long representation of timestamp */
ObjectTimestampPair(T val, long time) { value = val; tstamp = time; }
Returns a string representation.
Returns:String representing this ObjectTimestampPair
/** * Returns a string representation. * * @return String representing this ObjectTimestampPair */
@Override public String toString() { return value + ";" + tstamp; }
Compares this to another object by casting the argument to an ObjectTimestampPair.
Params:
  • obj – object to cmpare
Returns:result of comparison
/** * Compares this to another object by casting the argument to an * ObjectTimestampPair. * * @param obj object to cmpare * @return result of comparison */
@SuppressWarnings("unchecked") public int compareTo(Object obj) { return compareTo((ObjectTimestampPair<T>) obj); }
Compares this to another ObjectTimestampPair, using the timestamp as basis for comparison. Implementation is consistent with equals.
Params:
  • other – object to compare
Returns:result of comparison
/** * Compares this to another ObjectTimestampPair, using the timestamp as basis for comparison. * Implementation is consistent with equals. * * @param other object to compare * @return result of comparison */
public int compareTo(ObjectTimestampPair<T> other) { final long tstampdiff = this.tstamp - other.tstamp; if (tstampdiff == 0) { // make sure the natural ordering is consistent with equals // see java.lang.Comparable Javadocs return System.identityHashCode(this) - System.identityHashCode(other); } else { // handle int overflow return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE); } }
Returns:the value
/** * @return the value */
public T getValue() { return value; }
Returns:the tstamp
/** * @return the tstamp */
public long getTstamp() { return tstamp; } }
The idle object evictor TimerTask.
See Also:
/** * The idle object evictor {@link TimerTask}. * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis */
private class Evictor extends TimerTask {
Run pool maintenance. Evict objects qualifying for eviction and then invoke GenericKeyedObjectPool.ensureMinIdle().
/** * Run pool maintenance. Evict objects qualifying for eviction and then * invoke {@link GenericKeyedObjectPool#ensureMinIdle()}. */
@Override public void run() { //Evict from the pool try { evict(); } catch(Exception e) { // ignored } catch(OutOfMemoryError oome) { // Log problem but give evictor thread a chance to continue in // case error is recoverable oome.printStackTrace(System.err); } //Re-create idle instances. try { ensureMinIdle(); } catch (Exception e) { // ignored } } }
A simple "struct" encapsulating the configuration information for a GenericKeyedObjectPool.
See Also:
/** * A simple "struct" encapsulating the * configuration information for a <code>GenericKeyedObjectPool</code>. * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config) * @see GenericKeyedObjectPool#setConfig */
public static class Config { //CHECKSTYLE: stop VisibilityModifier
See Also:
  • setMaxIdle.setMaxIdle
/** * @see GenericKeyedObjectPool#setMaxIdle */
public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
See Also:
  • setMaxActive.setMaxActive
/** * @see GenericKeyedObjectPool#setMaxActive */
public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
See Also:
  • setMaxTotal.setMaxTotal
/** * @see GenericKeyedObjectPool#setMaxTotal */
public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
See Also:
  • setMinIdle.setMinIdle
/** * @see GenericKeyedObjectPool#setMinIdle */
public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
See Also:
  • setMaxWait.setMaxWait
/** * @see GenericKeyedObjectPool#setMaxWait */
public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
See Also:
  • setWhenExhaustedAction.setWhenExhaustedAction
/** * @see GenericKeyedObjectPool#setWhenExhaustedAction */
public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
See Also:
  • setTestOnBorrow.setTestOnBorrow
/** * @see GenericKeyedObjectPool#setTestOnBorrow */
public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
See Also:
  • setTestOnReturn.setTestOnReturn
/** * @see GenericKeyedObjectPool#setTestOnReturn */
public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
See Also:
  • setTestWhileIdle.setTestWhileIdle
/** * @see GenericKeyedObjectPool#setTestWhileIdle */
public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
See Also:
  • setTimeBetweenEvictionRunsMillis.setTimeBetweenEvictionRunsMillis
/** * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis */
public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
See Also:
  • setNumTestsPerEvictionRun.setNumTestsPerEvictionRun
/** * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun */
public int numTestsPerEvictionRun = GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
See Also:
  • setMinEvictableIdleTimeMillis.setMinEvictableIdleTimeMillis
/** * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis */
public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
See Also:
  • setLifo.setLifo
/** * @see GenericKeyedObjectPool#setLifo */
public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO; //CHECKSTYLE: resume VisibilityModifier }
Latch used to control allocation order of objects to threads to ensure fairness. That is, for each key, objects are allocated to threads in the order that threads request objects.
Since:1.5
/** * Latch used to control allocation order of objects to threads to ensure * fairness. That is, for each key, objects are allocated to threads in the order * that threads request objects. * * @since 1.5 */
private final class Latch<LK, LV> {
key of associated pool
/** key of associated pool */
private final LK _key;
keyed pool associated with this latch
/** keyed pool associated with this latch */
private ObjectQueue _pool;
holds an ObjectTimestampPair when this latch has been allocated an instance
/** holds an ObjectTimestampPair when this latch has been allocated an instance */
private ObjectTimestampPair<LV> _pair;
indicates that this latch can create an instance
/** indicates that this latch can create an instance */
private boolean _mayCreate = false;
Create a latch with the given key
Params:
  • key – key of the pool associated with this latch
/** * Create a latch with the given key * @param key key of the pool associated with this latch */
private Latch(LK key) { _key = key; }
Retuns the key of the associated pool
Returns:associated pool key
/** * Retuns the key of the associated pool * @return associated pool key */
private synchronized LK getkey() { return _key; }
Returns the pool associated with this latch
Returns:pool
/** * Returns the pool associated with this latch * @return pool */
private synchronized ObjectQueue getPool() { return _pool; }
Sets the pool associated with this latch
Params:
  • pool – the pool
/** * Sets the pool associated with this latch * @param pool the pool */
private synchronized void setPool(ObjectQueue pool) { _pool = pool; }
Gets the ObjectTimestampPair allocated to this latch. Returns null if this latch does not have an instance allocated to it.
Returns:the associated ObjectTimestampPair
/** * Gets the ObjectTimestampPair allocated to this latch. * Returns null if this latch does not have an instance allocated to it. * @return the associated ObjectTimestampPair */
private synchronized ObjectTimestampPair<LV> getPair() { return _pair; }
Allocate an ObjectTimestampPair to this latch.
Params:
  • pair – ObjectTimestampPair on this latch
/** * Allocate an ObjectTimestampPair to this latch. * @param pair ObjectTimestampPair on this latch */
private synchronized void setPair(ObjectTimestampPair<LV> pair) { _pair = pair; }
Whether or not this latch can create an instance
Returns:true if this latch has an instance creation permit
/** * Whether or not this latch can create an instance * @return true if this latch has an instance creation permit */
private synchronized boolean mayCreate() { return _mayCreate; }
Sets the mayCreate property
Params:
  • mayCreate – true means this latch can create an instance
/** * Sets the mayCreate property * * @param mayCreate true means this latch can create an instance */
private synchronized void setMayCreate(boolean mayCreate) { _mayCreate = mayCreate; }
Reset the latch data. Used when an allocation fails and the latch needs to be re-added to the queue.
/** * Reset the latch data. Used when an allocation fails and the latch * needs to be re-added to the queue. */
private synchronized void reset() { _pair = null; _mayCreate = false; } } //--- protected attributes ---------------------------------------
The cap on the number of idle instances in the pool.
See Also:
/** * The cap on the number of idle instances in the pool. * @see #setMaxIdle * @see #getMaxIdle */
private int _maxIdle = DEFAULT_MAX_IDLE;
The minimum no of idle objects to keep in the pool.
See Also:
/** * The minimum no of idle objects to keep in the pool. * @see #setMinIdle * @see #getMinIdle */
private volatile int _minIdle = DEFAULT_MIN_IDLE;
The cap on the number of active instances from the pool.
See Also:
/** * The cap on the number of active instances from the pool. * @see #setMaxActive * @see #getMaxActive */
private int _maxActive = DEFAULT_MAX_ACTIVE;
The cap on the total number of instances from the pool if non-positive.
See Also:
/** * The cap on the total number of instances from the pool if non-positive. * @see #setMaxTotal * @see #getMaxTotal */
private int _maxTotal = DEFAULT_MAX_TOTAL;
The maximum amount of time (in millis) the borrowObject method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject method may block indefinitely.
See Also:
/** * The maximum amount of time (in millis) the * {@link #borrowObject} method should block before throwing * an exception when the pool is exhausted and the * {@link #getWhenExhaustedAction "when exhausted" action} is * {@link #WHEN_EXHAUSTED_BLOCK}. * * When less than or equal to 0, the {@link #borrowObject} method * may block indefinitely. * * @see #setMaxWait * @see #getMaxWait * @see #WHEN_EXHAUSTED_BLOCK * @see #setWhenExhaustedAction * @see #getWhenExhaustedAction */
private long _maxWait = DEFAULT_MAX_WAIT;
The action to take when the borrowObject method is invoked when the pool is exhausted (the maximum number of "active" objects has been reached).
See Also:
/** * The action to take when the {@link #borrowObject} method * is invoked when the pool is exhausted (the maximum number * of "active" objects has been reached). * * @see #WHEN_EXHAUSTED_BLOCK * @see #WHEN_EXHAUSTED_FAIL * @see #WHEN_EXHAUSTED_GROW * @see #DEFAULT_WHEN_EXHAUSTED_ACTION * @see #setWhenExhaustedAction * @see #getWhenExhaustedAction */
private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
When true, objects will be validated before being returned by the borrowObject method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned by the {@link #borrowObject} * method. If the object fails to validate, * it will be dropped from the pool, and we will attempt * to borrow another. * * @see #setTestOnBorrow * @see #getTestOnBorrow */
private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
When true, objects will be validated before being returned to the pool within the returnObject.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * before being returned to the pool within the * {@link #returnObject}. * * @see #getTestOnReturn * @see #setTestOnReturn */
private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
When true, objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool.
See Also:
/** * When <code>true</code>, objects will be * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated} * by the idle object evictor (if any). If an object * fails to validate, it will be dropped from the pool. * * @see #setTestWhileIdle * @see #getTestWhileIdle * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.
See Also:
/** * The number of milliseconds to sleep between runs of the * idle object evictor thread. * When non-positive, no idle object evictor thread will be * run. * * @see #setTimeBetweenEvictionRunsMillis * @see #getTimeBetweenEvictionRunsMillis */
private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
The number of objects to examine during each run of the idle object evictor thread (if any).

When a negative value is supplied, ceil(getNumIdle)/abs(getNumTestsPerEvictionRun) tests will be run. I.e., when the value is -n, roughly one nth of the idle objects will be tested per run.

See Also:
/** * The number of objects to examine during each run of the * idle object evictor thread (if any). * <p> * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code> * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the * idle objects will be tested per run. * * @see #setNumTestsPerEvictionRun * @see #getNumTestsPerEvictionRun * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
private int _numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
The minimum amount of time an object may sit idle in the pool before it is eligible for eviction by the idle object evictor (if any). When non-positive, no objects will be evicted from the pool due to idle time alone.
See Also:
/** * The minimum amount of time an object may sit idle in the pool * before it is eligible for eviction by the idle object evictor * (if any). * When non-positive, no objects will be evicted from the pool * due to idle time alone. * * @see #setMinEvictableIdleTimeMillis * @see #getMinEvictableIdleTimeMillis * @see #getTimeBetweenEvictionRunsMillis * @see #setTimeBetweenEvictionRunsMillis */
private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
My hash of pools (ObjectQueue).
/** My hash of pools (ObjectQueue). */
private Map<K, ObjectQueue> _poolMap = null;
The total number of active instances.
/** The total number of active instances. */
private int _totalActive = 0;
The total number of idle instances.
/** The total number of idle instances. */
private int _totalIdle = 0;
The number of objects subject to some form of internal processing (usually creation or destruction) that should be included in the total number of objects but are neither active nor idle.
/** * The number of objects subject to some form of internal processing * (usually creation or destruction) that should be included in the total * number of objects but are neither active nor idle. */
private int _totalInternalProcessing = 0; /** My {@link KeyedPoolableObjectFactory}. */ private KeyedPoolableObjectFactory<K, V> _factory = null;
My idle object eviction TimerTask, if any.
/** * My idle object eviction {@link TimerTask}, if any. */
private Evictor _evictor = null;
A cursorable list of my pools.
See Also:
  • run.run
/** * A cursorable list of my pools. * @see GenericKeyedObjectPool.Evictor#run */
private CursorableLinkedList<K> _poolList = null;
Eviction cursor (over instances within-key)
/** Eviction cursor (over instances within-key) */
private CursorableLinkedList<ObjectTimestampPair<V>>.Cursor _evictionCursor = null;
Eviction cursor (over keys)
/** Eviction cursor (over keys) */
private CursorableLinkedList<K>.Cursor _evictionKeyCursor = null;
Whether or not the pools behave as LIFO queues (last in first out)
/** Whether or not the pools behave as LIFO queues (last in first out) */
private boolean _lifo = DEFAULT_LIFO;
Used to track the order in which threads call borrowObject() so that objects can be allocated in the order in which the threads requested them.
/** * Used to track the order in which threads call {@link #borrowObject()} so * that objects can be allocated in the order in which the threads requested * them. */
private LinkedList<Latch<K, V>> _allocationQueue = new LinkedList<Latch<K, V>>(); }