A configurable
KeyedObjectPool
implementation modifying the standard version coming with commons-pool to not lock each and every pool access which led to scalability issues and even deadlocks (TAPESTRY-2530, TAPESTRY-2382). TODO: switch back to the standard version once it works better.
When coupled with the appropriate {@link 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 {@link #preparePool preparePool}, {@link #addObject addObject} or{@link #borrowObject borrowObject} methods. Each time a new key value isprovided 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:
- {@link #setMaxActive maxActive} controls the maximum number of objects(per key) that can be borrowed from the pool at one time. When non-positive, there is no limit to the number of objects per key. When {@link #setMaxActive maxActive} is exceeded, the keyed pool is saidto be exhausted. The default setting for this parameter is 8.
- {@link #setMaxTotal maxTotal} sets a global limit on the number of objectsthat 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
maxTotal
is set to a positive value and {@link #borrowObject borrowObject} is invokedwhen 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). - {@link #setMaxIdle maxIdle} controls the maximum number of objects that cansit 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.
- {@link #setWhenExhaustedAction whenExhaustedAction} specifies thebehavior of the {@link #borrowObject borrowObject} method when a keyedpool is exhausted:
- When {@link #setWhenExhaustedAction whenExhaustedAction} is{@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throwa {@link NoSuchElementException}
- When {@link #setWhenExhaustedAction whenExhaustedAction} is{@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a newobject and return it (essentially making {@link #setMaxActive maxActive}meaningless.)
- 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 atmost 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.
The default whenExhaustedAction
setting is {@link #WHEN_EXHAUSTED_BLOCK}. - When {@link #setTestOnBorrow testOnBorrow} is set, the pool willattempt 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
false.
- When {@link #setTestOnReturn testOnReturn} is set, the pool willattempt 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
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 require an exclusive synchronization lock on the pool, so if they run too frequently and / or incur excessive latency when creating, destroying or validating object instances, performance issues may result. The idle object eviction thread may be configured using the following attributes:
- {@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).
- {@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
timeBetweenEvictionRunsMillis > 0.
The default setting for this parameter is 30 minutes. - {@link #setTestWhileIdle testWhileIdle} indicates whether or not idleobjects should be validated using the factory's {@link KeyedPoolableObjectFactory#validateObject validateObject} methodduring 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.
- {@link #setMinIdle minIdle} sets a target value for the minimum number ofidle 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 {@link #preparePool 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.
- {@link #setLifo 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 {@link KeyedPoolableObjectFactory}. A non-null
factory must be provided either as a constructor argument or via a call to {@link #setFactory setFactory} before the pool is used.
@see GenericObjectPool
@author Rodney Waldhoff
@author Dirk Verbeeck
@author Sandy McArthur
@version $Revision: 620830 $ $Date: 2008-02-12 16:41:58 +0100 (Di, 12 Feb 2008) $
@since Pool 1.0