/*
* 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:
-
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 maxActive
is reached, the keyed pool is said to be exhausted. The default setting for this parameter is 8.
-
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 maxTotal
is exceeded, all keyed pools are exhausted. 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. The default setting for this parameter is -1 (no limit).
-
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.
-
whenExhaustedAction
specifies the behavior of the borrowObject
method when a keyed pool is exhausted:
- When
whenExhaustedAction
is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_FAIL
, borrowObject
will throw a NoSuchElementException
- When
whenExhaustedAction
is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_GROW
, borrowObject
will create a new object and return it (essentially making maxActive
meaningless.)
- When
whenExhaustedAction
is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK
, borrowObject
will block (invoke wait
until a new or idle object is available. If a positive maxWait
value is supplied, the borrowObject
will block for at most that many milliseconds, after which a NoSuchElementException
will be thrown. If maxWait
is non-positive, the borrowObject
method will block indefinitely.
The default whenExhaustedAction
setting is GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK
.
- When
testOnBorrow
is set, the pool will attempt to validate each object before it is returned from the borrowObject
method. (Using the provided factory's 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 false.
- When
testOnReturn
is set, the pool will attempt to validate each object before it is returned to the pool in the returnObject
method. (Using the provided factory's validateObject
method.) Objects that fail to validate will be dropped from the pool. The default setting for this parameter is false.
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: 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: - getMaxIdle
- setMaxIdle
/**
* 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: - getMaxActive
- setMaxActive
/**
* 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: - getMaxTotal
- setMaxTotal
/**
* 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: - getTestOnBorrow
- setTestOnBorrow
/**
* 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: - getTestOnReturn
- setTestOnReturn
/**
* 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: - getTimeBetweenEvictionRunsMillis
- setTimeBetweenEvictionRunsMillis
/**
* 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: - getNumTestsPerEvictionRun
- setNumTestsPerEvictionRun
- getTimeBetweenEvictionRunsMillis
- setTimeBetweenEvictionRunsMillis
/**
* 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: - GenericKeyedObjectPool(KeyedPoolableObjectFactory)
- setFactory(KeyedPoolableObjectFactory)
/**
* 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: - whenExhaustedAction – the action code, which must be one of
GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_BLOCK
, GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_FAIL
, or GenericKeyedObjectPool<K,V>.WHEN_EXHAUSTED_GROW
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;
}
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;
}
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 n
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.
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 queuesSince: 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: - NoSuchElementException – if a keyed object instance cannot be returned.
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: - Exception – when
KeyedPoolableObjectFactory.makeObject
fails. - IllegalStateException – when no
factory
has been set or after close
has been called on this pool.
/**
* 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: - getMinIdle
- setMinIdle
/**
* 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: - GenericKeyedObjectPool.GenericKeyedObjectPool(KeyedPoolableObjectFactory, Config)
- GenericKeyedObjectPool.setConfig
/**
* 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: - setMaxIdle
- getMaxIdle
/**
* 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: - setMinIdle
- getMinIdle
/**
* 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: - setMaxActive
- getMaxActive
/**
* 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: - setMaxTotal
- getMaxTotal
/**
* 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;
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: - setTimeBetweenEvictionRunsMillis
- getTimeBetweenEvictionRunsMillis
/**
* 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 n
th 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: - setMinEvictableIdleTimeMillis
- getMinEvictableIdleTimeMillis
- getTimeBetweenEvictionRunsMillis
- setTimeBetweenEvictionRunsMillis
/**
* 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>>();
}