Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * 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.HashMap;
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeMap;
  
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 org.apache.commons.pool.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 be borrowed from the pool at one time. When non-positive, there is no limit to the number of objects per key. When maxActive is exceeded, 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 WHEN_EXHAUSTED_FAIL, borrowObject will throw a java.util.NoSuchElementException
    • When whenExhaustedAction is WHEN_EXHAUSTED_GROW, borrowObject will create a new object and return it (essentially making maxActive meaningless.)
    • When whenExhaustedAction is 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 java.util.NoSuchElementException will be thrown. If maxWait is non-positive, the borrowObject method will block indefinitely.
    The default whenExhaustedAction setting is 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 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:

  • 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 org.apache.commons.pool.KeyedPoolableObjectFactory. A non-null factory must be provided either as a constructor argument or via a call to setFactory before the pool is used.

Author(s):
Rodney Waldhoff
Dirk Verbeeck
Sandy McArthur
Version:
$Revision: 620830 $ $Date: 2008-02-12 16:41:58 +0100 (Di, 12 Feb 2008) $
Since:
Pool 1.0
See also:
org.apache.commons.pool.impl.GenericObjectPool
 
 public class TapestryKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
 
     //--- 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(java.lang.Object) method should fail, throwing a java.util.NoSuchElementException.

 
     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(java.lang.Object) method should block until a new object is available, or the maximum wait time has been reached.

 
     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(java.lang.Object) method should simply create a new object anyway.

 
     public static final byte WHEN_EXHAUSTED_GROW   = 2;

    
The default cap on the number of idle instances (per key) in the pool.

 
     public static final int DEFAULT_MAX_IDLE  = 8;

    
The default cap on the total number of active instances (per key) from the pool.

 
     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.

 
     public static final int DEFAULT_MAX_TOTAL  = -1;

    
The default "when exhausted action" for the pool.

 
     public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = ;

    
The default maximum amount of time (in milliseconds) the borrowObject(java.lang.Object) method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is WHEN_EXHAUSTED_BLOCK.

 
     public static final long DEFAULT_MAX_WAIT = -1L;

    
The default "test on borrow" value.

 
     public static final boolean DEFAULT_TEST_ON_BORROW = false;

    
The default "test on return" value.

 
     public static final boolean DEFAULT_TEST_ON_RETURN = false;

    
 
     public static final boolean DEFAULT_TEST_WHILE_IDLE = false;

    
The default "time between eviction runs" value.

 
     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.

 
     public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;

    
 
     public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;

    
The default minimum level of idle objects in the pool.

Since:
Pool 1.3
See also:
setMinIdle(int)
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.

 
     public static final boolean DEFAULT_LIFO = true;
     
     //--- constructors -----------------------------------------------
 
    
 
     public TapestryKeyedObjectPool() {
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
factory the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
 
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
factory the KeyedPoolableObjectFactory to use to create, validate, and destroy objects if not null
config a non-null org.apache.commons.pool.impl.GenericKeyedObjectPool.Config describing the configuration
 
         this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.maxTotalconfig.minIdle,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle,config.lifo);
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActive) {
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWait) {
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitboolean testOnBorrowboolean testOnReturn) {
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdle) {
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see getMaxWait())
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdleboolean testOnBorrowboolean testOnReturn) {
         this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,testOnBorrow,testOnReturn,,,,);
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis(long))
numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun(int))
minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis(long))
testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle(boolean))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillisint numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdle.testOnBorrowtestOnReturntimeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle);
     }

    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
maxTotal the maximum number of objects that can exists at one time (see setMaxTotal(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis(long))
numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun(int))
minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis(long))
testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle(boolean))
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdleint maxTotalboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillisint numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdlemaxTotal.testOnBorrowtestOnReturntimeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle);
     }
    
    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
maxTotal the maximum number of objects that can exists at one time (see setMaxTotal(int))
minIdle the minimum number of idle objects to have in the pool at any one time (see setMinIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis(long))
numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun(int))
minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis(long))
testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle(boolean))
Since:
Pool 1.3
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdleint maxTotalint minIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillisint numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdlemaxTotalminIdletestOnBorrowtestOnReturntimeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle);
     }
    
    
Create a new GenericKeyedObjectPool using the specified values.

Parameters:
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(int))
whenExhaustedAction the action to take when the pool is exhausted (see setWhenExhaustedAction(byte))
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see setMaxWait(long))
maxIdle the maximum number of idle objects in my pool (see setMaxIdle(int))
maxTotal the maximum number of objects that can exists at one time (see setMaxTotal(int))
minIdle the minimum number of idle objects to have in the pool at any one time (see setMinIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject(java.lang.Object) method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object,java.lang.Object) method (see setTestOnReturn(boolean))
timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see setTimeBetweenEvictionRunsMillis(long))
numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see setNumTestsPerEvictionRun(int))
minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see setMinEvictableIdleTimeMillis(long))
testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see setTestWhileIdle(boolean))
lifo whether or not the pools behave as LIFO (last in first out) queues (see setLifo(boolean))
Since:
Pool 1.4
 
     public TapestryKeyedObjectPool(KeyedPoolableObjectFactory factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdleint maxTotalint minIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillisint numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdleboolean lifo) {
          = factory;
          = maxActive;
          = lifo;
         switch(whenExhaustedAction) {
             case :
             case :
             case :
                  = whenExhaustedAction;
                 break;
             default:
                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
         }
          = maxWait;
          = maxIdle;
          = maxTotal;
          = minIdle;
          = testOnBorrow;
          = testOnReturn;
          = timeBetweenEvictionRunsMillis;
          = numTestsPerEvictionRun;
          = minEvictableIdleTimeMillis;
          = testWhileIdle;
 
          = new HashMap();
          = new CursorableLinkedList();
 
     }
 
     //--- public methods ---------------------------------------------
 
     //--- configuration methods --------------------------------------
 
    
Returns the cap on the number of active instances per key. A negative value indicates no limit.

Returns:
the cap on the number of active instances per key.
See also:
setMaxActive(int)
 
     public synchronized int getMaxActive() {
         return ;
     }

    
Sets the cap on the number of active instances per key.

Parameters:
maxActive The cap on the number of active instances per key. Use a negative value for no limit.
See also:
getMaxActive()
 
     public synchronized void setMaxActive(int maxActive) {
          = maxActive;
         notifyAll();
     }

    
Returns the overall maximum number of objects (across pools) that can exist at one time. A negative value indicates no limit.

Returns:
the maximum number of instances in circulation at one time.
See also:
setMaxTotal(int)
 
     public synchronized int getMaxTotal() {
         return ;
     }

    
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.

Parameters:
maxTotal The cap on the total number of instances across pools. Use a negative value for no limit.
See also:
getMaxTotal()
 
     public synchronized void setMaxTotal(int maxTotal) {
          = maxTotal;
         notifyAll();
     }

    
Returns the action to take when the borrowObject(java.lang.Object) method is invoked when the pool is exhausted (the maximum number of "active" objects has been reached).

 
     public synchronized byte getWhenExhaustedAction() {
         return ;
     }

    
Sets the action to take when the borrowObject(java.lang.Object) method is invoked when the pool is exhausted (the maximum number of "active" objects has been reached).

Parameters:
whenExhaustedAction the action code, which must be one of WHEN_EXHAUSTED_BLOCK, WHEN_EXHAUSTED_FAIL, or WHEN_EXHAUSTED_GROW
See also:
getWhenExhaustedAction()
 
     public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
         switch(whenExhaustedAction) {
             case :
             case :
             case :
                  = whenExhaustedAction;
                 notifyAll();
                 break;
             default:
                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
         }
     }


    
Returns the maximum amount of time (in milliseconds) the borrowObject(java.lang.Object) method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject(java.lang.Object) method may block indefinitely.

Returns:
the maximum number of milliseconds borrowObject will block.
See also:
setMaxWait(long)
setWhenExhaustedAction(byte)
WHEN_EXHAUSTED_BLOCK
 
     public synchronized long getMaxWait() {
         return ;
     }

    
Sets the maximum amount of time (in milliseconds) the borrowObject(java.lang.Object) method should block before throwing an exception when the pool is exhausted and the "when exhausted" action is WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject(java.lang.Object) method may block indefinitely.

Parameters:
maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely.
See also:
getMaxWait()
setWhenExhaustedAction(byte)
WHEN_EXHAUSTED_BLOCK
 
     public synchronized void setMaxWait(long maxWait) {
          = maxWait;
     }

    
Returns the cap on the number of "idle" instances per key.

Returns:
the maximum number of "idle" instances that can be held in a given keyed pool.
See also:
setMaxIdle(int)
 
     public synchronized int getMaxIdle() {
         return ;
     }

    
Sets the cap on the number of "idle" instances in the pool.

Parameters:
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:
getMaxIdle()
DEFAULT_MAX_IDLE
 
     public synchronized void setMaxIdle(int maxIdle) {
          = maxIdle;
         notifyAll();
     }

    
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.

Parameters:
poolSize - The minimum size of the each keyed pool
Since:
Pool 1.3
See also:
getMinIdle()
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized void setMinIdle(int poolSize) {
          = 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.

Returns:
minimum size of the each keyed pool
Since:
Pool 1.3
See also:
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized int getMinIdle() {
         return ;
     }

    
When true, objects will be validated before being returned by the borrowObject(java.lang.Object) method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.

Returns:
true if objects are validated before being borrowed.
See also:
setTestOnBorrow(boolean)
 
     public boolean getTestOnBorrow() {
         return ;
     }

    
When true, objects will be validated before being returned by the borrowObject(java.lang.Object) method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.

Parameters:
testOnBorrow whether object should be validated before being returned by borrowObject.
See also:
getTestOnBorrow()
 
     public void setTestOnBorrow(boolean testOnBorrow) {
          = testOnBorrow;
     }

    
When true, objects will be validated before being returned to the pool within the returnObject(java.lang.Object,java.lang.Object).

Returns:
true when objects will be validated before being returned.
See also:
setTestOnReturn(boolean)
 
     public boolean getTestOnReturn() {
         return ;
     }

    
When true, objects will be validated before being returned to the pool within the returnObject(java.lang.Object,java.lang.Object).

Parameters:
testOnReturn true so objects will be validated before being returned.
See also:
getTestOnReturn()
 
     public void setTestOnReturn(boolean 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.

Returns:
milliseconds to sleep between evictor runs.
See also:
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized long getTimeBetweenEvictionRunsMillis() {
         return ;
     }

    
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.

Parameters:
timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs.
See also:
getTimeBetweenEvictionRunsMillis()
 
     public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
          = timeBetweenEvictionRunsMillis;
     }

    
Returns the number of objects to examine during each run of the idle object evictor thread (if any).

Returns:
number of objects to examine each eviction run.
See also:
setNumTestsPerEvictionRun(int)
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized int getNumTestsPerEvictionRun() {
         return ;
     }

    
Sets the number of objects to examine during each run of the idle object evictor thread (if any).

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

Parameters:
numTestsPerEvictionRun number of objects to examine each eviction run.
See also:
getNumTestsPerEvictionRun()
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized void setNumTestsPerEvictionRun(int 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).

Returns:
minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
See also:
setMinEvictableIdleTimeMillis(long)
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized long getMinEvictableIdleTimeMillis() {
         return ;
     }

    
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.

Parameters:
minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
See also:
getMinEvictableIdleTimeMillis()
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized void setMinEvictableIdleTimeMillis(long 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.

Returns:
true when objects are validated when borrowed.
See also:
setTestWhileIdle(boolean)
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized boolean getTestWhileIdle() {
         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.

Parameters:
testWhileIdle true so objects are validated when borrowed.
See also:
getTestWhileIdle()
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized void setTestWhileIdle(boolean testWhileIdle) {
          = testWhileIdle;
     }

    
Sets the configuration.

Parameters:
conf the new configuration to use.
See also:
org.apache.commons.pool.impl.GenericKeyedObjectPool.Config
 
     public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
         setMaxIdle(conf.maxIdle);
         setMaxActive(conf.maxActive);
         setMaxTotal(conf.maxTotal);
         setMinIdle(conf.minIdle);
         setMaxWait(conf.maxWait);
         setWhenExhaustedAction(conf.whenExhaustedAction);
         setTestOnBorrow(conf.testOnBorrow);
         setTestOnReturn(conf.testOnReturn);
         setTestWhileIdle(conf.testWhileIdle);
         setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
         setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
         setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
     }
    
    
Whether or not the idle object pools act as LIFO queues. True means that borrowObject returns the most recently used ("last in") idle object in a pool (if there are idle instances available). False means that the pools behave as FIFO queues - objects are taken from idle object pools in the order that they are returned.

Returns:
true if the pools are configured to act as LIFO queues
Since:
1.4
 
      public synchronized boolean getLifo() {
          return ;
      }

     
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.

Parameters:
lifo the new value for the lifo property
Since:
1.4
 
      public synchronized void setLifo(boolean lifo) {
          this. = lifo;
      }
 
     //-- ObjectPool methods ------------------------------------------
 
     public Object borrowObject(Object keythrows Exception {
         long starttime = System.currentTimeMillis();
         boolean newlyCreated = false;
         for(;;) {
             ObjectTimestampPair pair = null;
             ObjectQueue pool = null;
             synchronized () {
                 assertOpen();
                 pool = (ObjectQueue)(.get(key));
                 if(null == pool) {
                     pool = new ObjectQueue();
                     .put(key,pool);
                     .add(key);
                 }
             }
                 // if there are any sleeping, just grab one of those
                 try {
                 	synchronized (pool) {
                 		pair = (ObjectTimestampPair)(pool.queue.removeFirst());
                 	}
                     if(null != pair) {
                         --;
                     }
                 } catch(NoSuchElementException e) { /* ignored */
                 }
                 // otherwise
                 if(null == pair) {
                     // if there is a totalMaxActive and we are at the limit then
                     // we have to make room
                     if (( > 0) && ( +  >= )) {
                         clearOldest();
                     }
     
                     // check if we can create one
                     // (note we know that the num sleeping is 0, else we wouldn't be here)
                     if (( < 0 || pool.activeCount < ) &&
                         ( < 0 ||  +  < )) {
                         Object obj = .makeObject(key);
                         pair = new ObjectTimestampPair(obj);
                         newlyCreated = true;
                     } else {
                         // the pool is exhausted
                         switch() {
                             case :
                                 Object obj = .makeObject(key);
                                 pair = new ObjectTimestampPair(obj);
                                 break;
                             case :
                                 throw new NoSuchElementException();
                             case :
                                 try {
                                     if( <= 0) {
                                         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 =  - elapsed;
                                         if (waitTime > 0)
                                         {
                                             wait(waitTime);
                                         }
                                     }
                                 } catch(InterruptedException e) {
                                     // ignored
                                 }
                                if( > 0 && ((System.currentTimeMillis() - starttime) >= )) {
                                    throw new NoSuchElementException("Timeout waiting for idle object");
                                } else {
                                    continue// keep looping
                                }
                            default:
                                throw new IllegalArgumentException("whenExhaustedAction " +  + " not recognized.");
                        }
                    }
                
                pool.incrementActiveCount();
            }
            
            // Activate.  If activate fails, decrement active count and destroy.
            // If instance failing activation is new, throw NoSuchElementException;
            // otherwise keep looping
            try {
                .activateObject(keypair.value);
            } catch (Exception e) {
                try {
                    .destroyObject(key,pair.value);
                    synchronized (this) {
                        pool.decrementActiveCount();
                    }
                } catch (Exception e2) {
                    // swallowed
                }
                if(newlyCreated) {
                    throw new NoSuchElementException(
                       "Could not create a validated object, cause: "
                            + e.getMessage());
                }
                else {
                    continue// keep looping
                }
            }
            // Validate.  If validation fails, decrement active count and
            // destroy. If instance failing validation is new, throw
            // NoSuchElementException; otherwise keep looping
            boolean invalid = true;
            try {
                invalid =  && !.validateObject(keypair.value);
            } catch (Exception e) {
                // swallowed
            }
            if (invalid) {
                try {
                    .destroyObject(key,pair.value);
                    synchronized (pool) {
                        pool.decrementActiveCount();
                    }
                } catch (Exception e) {
                    // swallowed
                }
                if(newlyCreated) {
                    throw new NoSuchElementException("Could not create a validated object");
                } // else keep looping
            } else {
                return pair.value;
            }
        }
    }

    
Clears the pool, removing all pooled instances.
    public synchronized void clear() {
        for(Iterator entries = .entrySet().iterator(); entries.hasNext(); ) {
            final Map.Entry entry = (Map.Entry)entries.next();
            final Object key = entry.getKey();
            final CursorableLinkedList list = ((ObjectQueue)(entry.getValue())).;
            for(Iterator it = list.iterator(); it.hasNext(); ) {
                try {
                    .destroyObject(key,((ObjectTimestampPair)(it.next())).);
                } catch(Exception e) {
                    // ignore error, keep destroying the rest
                }
                it.remove();
            }
        }
        .clear();
        .clear();
         = 0;
        notifyAll();
    }

    
Method 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 synchronized void clearOldest() {
        // build sorted map of idle objects
        final Map map = new TreeMap();
        for (Iterator keyiter = .keySet().iterator(); keyiter.hasNext();) {
            final Object key = keyiter.next();
            final CursorableLinkedList list = ((ObjectQueue).get(key)).;
            for (Iterator 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 setPairKeys = map.entrySet();
        int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
        Iterator iter = setPairKeys.iterator();
        while (iter.hasNext() && itemsToRemove > 0) {
            Map.Entry entry = (Map.Entryiter.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.
            Object key = entry.getValue();
            ObjectTimestampPair pairTimeStamp = (ObjectTimestampPairentry.getKey();
            final CursorableLinkedList list = 
                ((ObjectQueue)(.get(key))).;
            list.remove(pairTimeStamp);
            try {
                .destroyObject(keypairTimeStamp.value);
            } catch (Exception e) {
                // ignore error, keep destroying the rest
            }
            // if that was the last object for that key, drop that pool
            if (list.isEmpty()) {
                .remove(key);
                .remove(key);
            }
            --;
            itemsToRemove--;
        }
        notifyAll();
    }

    
Clears the specified pool, removing all pooled instances corresponding to the given key.

Parameters:
key the key to clear
    public synchronized void clear(Object key) {
        final ObjectQueue pool = (ObjectQueue)(.remove(key));
        if(null == pool) {
            return;
        } else {
            .remove(key);
            for(Iterator it = pool.queue.iterator(); it.hasNext(); ) {
                try {
                    .destroyObject(key,((ObjectTimestampPair)(it.next())).);
                } catch(Exception e) {
                    // ignore error, keep destroying the rest
                }
                it.remove();
                --;
            }
        }
        
        notifyAll();
    }

    
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
    public synchronized int getNumActive() {
        return ;
    }

    
Returns the total number of instances currently idle in this pool.

Returns:
the total number of instances currently idle in this pool
    public synchronized int getNumIdle() {
        return ;
    }

    
Returns the number of instances currently borrowed from but not yet returned to the pool corresponding to the given key.

Parameters:
key the key to query
Returns:
the number of instances corresponding to the given key currently borrowed in this pool
    public synchronized int getNumActive(Object key) {
        final ObjectQueue pool = (ObjectQueue)(.get(key));
        return pool != null ? pool.activeCount : 0;
    }

    
Returns the number of instances corresponding to the given key currently idle in this pool.

Parameters:
key the key to query
Returns:
the number of instances corresponding to the given key currently idle in this pool
    public synchronized int getNumIdle(Object key) {
        final ObjectQueue pool = (ObjectQueue)(.get(key));
        return pool != null ? pool.queue.size() : 0;
    }
    public void returnObject(Object keyObject objthrows Exception {
        try {
            addObjectToPool(keyobjtrue);
        } catch (Exception e) {
            if ( != null) {
                try {
                    .destroyObject(keyobj);
                } 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 = (ObjectQueue) (.get(key));
                if (pool != null) {
                    synchronized(pool) {
                        pool.decrementActiveCount();
                        notifyAll();
                    }  
                }
            }
        }
    }
    private void addObjectToPool(Object keyObject obj,
            boolean decrementNumActivethrows Exception {
        // if we need to validate this object, do so
        boolean success = true// whether or not this object passed validation
        if( && !.validateObject(keyobj)) {
            success = false;
        } else {
            .passivateObject(keyobj);
        }
        boolean shouldDestroy = !success;
        ObjectQueue pool;
        
        // Add instance to pool if there is room and it has passed validation
        // (if testOnreturn is set)
        synchronized (this) {
            // grab the pool (list) of objects associated with the given key
            pool = (ObjectQueue) (.get(key));
            // if it doesn't exist, create it
            if(null == pool) {
                pool = new ObjectQueue();
                .put(keypool);
                .add(key);
            }
        }
        synchronized (pool) {
            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( >= 0 && (pool.queue.size() >= )) {
                    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 () {
                        pool.queue.addFirst(new ObjectTimestampPair(obj)); 
                    } else {
                        pool.queue.addLast(new ObjectTimestampPair(obj));
                    }
                    ++;
                }
            }
        }
        // Destroy the instance if necessary 
        if(shouldDestroy) {
            try {
                .destroyObject(keyobj);
            } catch(Exception e) {
                // ignored?
            }
        }
        
        // Decrement active count *after* destroy if applicable
        if (decrementNumActive) {
            synchronized(this) {
                pool.decrementActiveCount();
                notifyAll();
            }
        }
    }
    public void invalidateObject(Object keyObject objthrows Exception {
        try {
            .destroyObject(keyobj);
        } finally {
            synchronized (this) {
                ObjectQueue pool = (ObjectQueue) (.get(key));
                if(null == pool) {
                    pool = new ObjectQueue();
                    .put(keypool);
                    .add(key);
                }
                pool.decrementActiveCount();
                notifyAll(); // _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.

Parameters:
key the key a new instance should be added to
Throws:
java.lang.Exception when org.apache.commons.pool.KeyedPoolableObjectFactory.makeObject(java.lang.Object) fails.
java.lang.IllegalStateException when no factory has been set or after close() has been called on this pool.
    public void addObject(Object keythrows Exception {
        assertOpen();
        if ( == null) {
            throw new IllegalStateException("Cannot add objects without a factory.");
        }
        Object obj = .makeObject(key);
        synchronized (this) {
            try {
                assertOpen();
                addObjectToPool(keyobjfalse);
            } catch (IllegalStateException ex) { // Pool closed
                try {
                    .destroyObject(keyobj);
                } 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.

Parameters:
key - The key to register for pool control.
populateImmediately - If this is true, the pool will be populated immediately.
Since:
Pool 1.3
    public synchronized void preparePool(Object keyboolean populateImmediately) {
        ObjectQueue pool = (ObjectQueue)(.get(key));
        if (null == pool) {
            pool = new ObjectQueue();
            .put(key,pool);
            .add(key);
        }
        if (populateImmediately) {
            try {
                // Create the pooled objects
                ensureMinIdle(key);
            }
            catch (Exception e) {
                //Do nothing
            }
        }
    }
    public void close() throws Exception {
        super.close();
        synchronized (this) {
            clear();
            if(null != ) {
                .close();
                 = null;
            }
            if(null != ) {
                .close();
                 = null;
            }
            startEvictor(-1L);
        }
    }
    public synchronized void setFactory(KeyedPoolableObjectFactory factorythrows IllegalStateException {
        assertOpen();
        if(0 < getNumActive()) {
            throw new IllegalStateException("Objects are already active");
        } else {
            clear();
             = factory;
        }
    }

    

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:
java.lang.Exception when there is a problem evicting idle objects.
    public synchronized void evict() throws Exception {
        // Initialize key to last key value
        Object key = null;
        if ( != null && 
                . != null) {
            key = ..value();
        }
        
        for (int i=0,m=getNumTests(); i<mi++) {
            // make sure pool map is not empty; otherwise do nothing
            if ( == null || .size() == 0) {
                continue;
            }
            // if we don't have a key cursor, then create one
            if (null == ) {
                resetEvictionKeyCursor();
                key = null;
            }
            // if we don't have an object cursor, create one
            if (null == ) {
                // if the _evictionKeyCursor has a next value, use this key
                if (.hasNext()) {
                    key = .next();
                    resetEvictionObjectCursor(key);
                } else {
                    // Reset the key cursor and try again
                    resetEvictionKeyCursor();
                    if ( != null) {
                        if (.hasNext()) {
                            key = .next();
                            resetEvictionObjectCursor(key);
                        }
                    }
                }
            }  
            if ( == null) {
                continue// should never happen; do nothing
            }
            // If eviction cursor is exhausted, try to move
            // to the next key and reset
            if(( && !.hasPrevious()) ||
                    (! && !.hasNext())) {
                if ( != null) {
                    if (.hasNext()) {
                        key = .next();
                        resetEvictionObjectCursor(key);
                    } else { // Need to reset Key cursor
                        resetEvictionKeyCursor();
                        if ( != null) {
                            if (.hasNext()) {
                                key = .next();
                                resetEvictionObjectCursor(key);
                            }
                        }
                    }
                }
            }
            if(( && !.hasPrevious()) ||
                    (! && !.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
            ObjectTimestampPair pair =  ? 
                    (ObjectTimestampPair.previous() : 
                    (ObjectTimestampPair.next();
            boolean removeObject=false;
            if(( > 0) &&
               (System.currentTimeMillis() - pair.tstamp > 
               )) {
                removeObject=true;
            }
            if( && removeObject == false) {
                boolean active = false;
                try {
                    .activateObject(key,pair.value);
                    active = true;
                } catch(Exception e) {
                    removeObject=true;
                }
                if(active) {
                    if(!.validateObject(key,pair.value)) {
                        removeObject=true;
                    } else {
                        try {
                            .passivateObject(key,pair.value);
                        } catch(Exception e) {
                            removeObject=true;
                        }
                    }
                }
            }
            if(removeObject) {
                try {
                    .remove();
                    --;
                    .destroyObject(keypair.value);
                    // Do not remove the key from the _poolList or _poolmap,
                    // even if the list stored in the _poolMap for this key is
                    // empty when minIdle > 0.
                    //
                    // Otherwise if it was the last object for that key,
                    // drop that pool
                    if ( == 0) {
                        ObjectQueue objectQueue = 
                            (ObjectQueue).get(key);
                        if (objectQueue != null && 
                                objectQueue.queue.isEmpty()) {
                            .remove(key);
                            .remove(key);  
                        }
                    }
                } catch(Exception e) {
                    ; // ignored
                }
            }
        }
    }
    
    
Resets the eviction key cursor and closes any associated eviction object cursor
    private void resetEvictionKeyCursor() {
        if ( != null) {
            .close();
        }
         = .cursor();
        if (null != ) {
            .close();
             = null;
        }  
    }
    
    
Resets the eviction object cursor for the given key

Parameters:
key eviction key
    private void resetEvictionObjectCursor(Object key) {
        if ( != null) {
            .close();
        }
        if ( == null) { 
            return;
        }
        ObjectQueue pool = (ObjectQueue) (.get(key));
        if (pool != null) {
            CursorableLinkedList queue = 
                (CursorableLinkedList)(pool.queue);
             = queue.cursor( ? queue.size() : 0);   
        }
    }

    
Iterates through all the known keys and creates any necessary objects to maintain the minimum level of pooled objects.

Throws:
java.lang.Exception If there was an error whilst creating the pooled objects.
See also:
getMinIdle()
setMinIdle(int)
    private synchronized void ensureMinIdle() throws Exception {
        Iterator iterator = .keySet().iterator();
        //Check if should sustain the pool
        if ( > 0) {
            // 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
            // Increment idle count + 1
            while (iterator.hasNext()) {
                //Get the next key to process
                Object key = iterator.next();
                ensureMinIdle(key);
            }
        }
    }

    
Re-creates any needed objects to maintain the minimum levels of pooled objects for the specified key. This method uses calculateDefecit(java.lang.Object) to calculate the number of objects to be created. calculateDefecit(java.lang.Object) can be overridden to provide a different method of calculating the number of objects to be created.

Parameters:
key The key to process
Throws:
java.lang.Exception If there was an error whilst creating the pooled objects
    private synchronized void ensureMinIdle(Object keythrows Exception {
        // Calculate current pool objects
        int numberToCreate = calculateDefecit(key);
        //Create required pool objects, if none to create, this loop will not be run.
        for (int i = 0; i < numberToCreatei++) {
            addObject(key);
        }
    }
    //--- non-public methods ----------------------------------------

    
Start the eviction thread or service, or when delay is non-positive, stop it if it is already running.

Parameters:
delay milliseconds between evictor runs.
    protected synchronized void startEvictor(long delay) {
        if(null != ) {
            EvictionTimer.cancel();
             = null;