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.List;
  
A configurable org.apache.commons.pool.ObjectPool implementation.

When coupled with the appropriate org.apache.commons.pool.PoolableObjectFactory, GenericObjectPool provides robust pooling functionality for arbitrary objects.

A GenericObjectPool provides a number of configurable parameters:

  • maxActive controls the maximum number of objects that can be allocated by the pool (checked out to clients, or idle awaiting checkout) at a given time. When non-positive, there is no limit to the number of objects that can be managed by the pool at one time. When maxActive is reached, the pool is said to be exhausted. The default setting for this parameter is 8.
  • maxIdle controls the maximum number of objects that can sit idle in the pool at any time. When negative, there is no limit to the number of objects that may be idle at one time. The default setting for this parameter is 8.
  • whenExhaustedAction specifies the behavior of the borrowObject() method when the pool is exhausted: The default whenExhaustedAction setting is WHEN_EXHAUSTED_BLOCK and the default maxWait setting is -1. By default, therefore, borrowObject will block indefinitely until an idle instance becomes available.
  • 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 org.apache.commons.pool.PoolableObjectFactory.validateObject(java.lang.Object) 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(java.lang.Object) method. (Using the provided factory's org.apache.commons.pool.PoolableObjectFactory.validateObject(java.lang.Object) 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 are available. 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., idle object eviction is disabled by default).
  • 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 org.apache.commons.pool.PoolableObjectFactory.validateObject(java.lang.Object) method. 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.
  • softMinEvictableIdleTimeMillis specifies 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), with the extra condition that at least "minIdle" object instances remain in the pool. When non-positive, no objects will be evicted from the pool due to idle time alone. This setting has no effect unless timeBetweenEvictionRunsMillis > 0. and it is superceded by minEvictableIdleTimeMillis (that is, if minEvictableIdleTimeMillis is positive, then softMinEvictableIdleTimeMillis is ignored). The default setting for this parameter is -1 (disabled).
  • numTestsPerEvictionRun determines the number of objects examined in each run of the idle object evictor. This setting has no effect unless timeBetweenEvictionRunsMillis > 0. The default setting for this parameter is 3.

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

  • lifo determines whether or not the pool returns idle objects in last-in-first-out order. The default setting for this parameter is true.

GenericObjectPool is not usable without a org.apache.commons.pool.PoolableObjectFactory. A non-null factory must be provided either as a constructor argument or via a call to setFactory(org.apache.commons.pool.PoolableObjectFactory) 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.

Parameters:
<T> the type of objects held in this pool
Author(s):
Rodney Waldhoff
Dirk Verbeeck
Sandy McArthur
Version:
$Revision: 1222396 $ $Date: 2011-12-22 14:02:25 -0500 (Thu, 22 Dec 2011) $
Since:
Pool 1.0
See also:
GenericKeyedObjectPool
 
 public class GenericObjectPool<T> extends BaseObjectPool<T> implements ObjectPool<T> {
 
     //--- 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 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() 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() method should simply create a new object anyway.

 
     public static final byte WHEN_EXHAUSTED_GROW   = 2;

    
The default cap on the number of "sleeping" instances in the pool.

 
     public static final int DEFAULT_MAX_IDLE  = 8;

    
The default minimum number of "sleeping" instances in the pool before before the evictor thread (if active) spawns new objects.

 
     public static final int DEFAULT_MIN_IDLE = 0;

    
The default cap on the total number of active instances from the pool.

See also:
getMaxActive()
 
     public static final int DEFAULT_MAX_ACTIVE  = 8;

    
The default "when exhausted action" for the pool.

 
     public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = ;

    
The default LIFO status. True means that borrowObject returns the most recently used ("last in") idle object in the pool (if there are idle instances available). False means that the pool behaves as a FIFO queue - objects are taken from the idle object pool in the order that they are returned to the pool.

Since:
1.4
See also:
setLifo(boolean)
 
     public static final boolean DEFAULT_LIFO = true;

    
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 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;

    
 
     public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
 
     //--- constructors -----------------------------------------------
 
    
Create a new GenericObjectPool with default properties.
 
     public GenericObjectPool() {
     }

    
Create a new GenericObjectPool using the specified factory.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
 
     public GenericObjectPool(PoolableObjectFactory<T> factory) {
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
config a non-null GenericObjectPool.Config describing my configuration
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryGenericObjectPool.Config config) {
         this(factoryconfig.maxActiveconfig.whenExhaustedActionconfig.maxWaitconfig.maxIdleconfig.minIdle,
                 config.testOnBorrowconfig.testOnReturnconfig.timeBetweenEvictionRunsMillis
                 config.numTestsPerEvictionRunconfig.minEvictableIdleTimeMillisconfig.testWhileIdle
                 config.softMinEvictableIdleTimeMillisconfig.lifo);
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed from me at one time (see setMaxActive(int))
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActive) {
         this(factorymaxActive,
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
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 getWhenExhaustedAction())
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see getMaxWait())
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait) {
         this(factorymaxActivewhenExhaustedActionmaxWait,
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed at one time (see setMaxActive(int))
whenExhaustedAction the action to take when the pool is exhausted (see getWhenExhaustedAction())
maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and whenExhaustedAction is WHEN_EXHAUSTED_BLOCK (otherwise ignored) (see getMaxWait())
testOnBorrow whether or not to validate objects before they are returned by the borrowObject() method (see getTestOnBorrow())
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object) method (see getTestOnReturn())
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             boolean testOnBorrowboolean testOnReturn) {
         this(factorymaxActivewhenExhaustedActionmaxWaittestOnBorrow,
                 testOnReturn,
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed at one time (see setMaxActive(int))
whenExhaustedAction the action to take when the pool is exhausted (see getWhenExhaustedAction())
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 getMaxIdle())
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWaitint maxIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdle,
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed at one time (see setMaxActive(int))
whenExhaustedAction the action to take when the pool is exhausted (see getWhenExhaustedAction())
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 getMaxIdle())
testOnBorrow whether or not to validate objects before they are returned by the borrowObject() method (see getTestOnBorrow())
testOnReturn whether or not to validate objects after they are returned to the returnObject(java.lang.Object) method (see getTestOnReturn())
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             int maxIdleboolean testOnBorrowboolean testOnReturn) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdletestOnBorrowtestOnReturn,
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed 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() method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(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 GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             int maxIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillis,
             int numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdletestOnBorrowtestOnReturn,
                 timeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle);
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed 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))
minIdle the minimum number of idle objects in my pool (see setMinIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject() method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(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 GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             int maxIdleint minIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillis,
             int numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdleminIdletestOnBorrowtestOnReturn,
                 timeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle,
                 );
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed 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))
minIdle the minimum number of idle objects in my pool (see setMinIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject() method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(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))
softMinEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction with the extra condition that at least "minIdle" amount of object remain in the pool. (see setSoftMinEvictableIdleTimeMillis(long))
Since:
Pool 1.3
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             int maxIdleint minIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillis,
             int numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle,
             long softMinEvictableIdleTimeMillis) {
         this(factorymaxActivewhenExhaustedActionmaxWaitmaxIdleminIdletestOnBorrowtestOnReturn,
                 timeBetweenEvictionRunsMillisnumTestsPerEvictionRunminEvictableIdleTimeMillistestWhileIdle,
                 softMinEvictableIdleTimeMillis);
     }

    
Create a new GenericObjectPool using the specified values.

Parameters:
factory the (possibly null)PoolableObjectFactory to use to create, validate and destroy objects
maxActive the maximum number of objects that can be borrowed 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))
minIdle the minimum number of idle objects in my pool (see setMinIdle(int))
testOnBorrow whether or not to validate objects before they are returned by the borrowObject() method (see setTestOnBorrow(boolean))
testOnReturn whether or not to validate objects after they are returned to the returnObject(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))
softMinEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction with the extra condition that at least "minIdle" amount of object remain in the pool. (see setSoftMinEvictableIdleTimeMillis(long))
lifo whether or not objects are returned in last-in-first-out order from the idle object pool (see setLifo(boolean))
Since:
Pool 1.4
 
     public GenericObjectPool(PoolableObjectFactory<T> factoryint maxActivebyte whenExhaustedActionlong maxWait,
             int maxIdleint minIdleboolean testOnBorrowboolean testOnReturnlong timeBetweenEvictionRunsMillis,
             int numTestsPerEvictionRunlong minEvictableIdleTimeMillisboolean testWhileIdle,
             long softMinEvictableIdleTimeMillisboolean lifo) {
          = factory;
          = maxActive;
          = lifo;
         switch(whenExhaustedAction) {
             case :
             case :
             case :
                  = whenExhaustedAction;
                 break;
             default:
                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
         }
          = maxWait;
          = maxIdle;
          = minIdle;
          = testOnBorrow;
          = testOnReturn;
          = timeBetweenEvictionRunsMillis;
          = numTestsPerEvictionRun;
          = minEvictableIdleTimeMillis;
          = softMinEvictableIdleTimeMillis;
          = testWhileIdle;
 
          = new CursorableLinkedList<ObjectTimestampPair<T>>();
     }
 
     //--- public methods ---------------------------------------------
 
     //--- configuration methods --------------------------------------
 
    
Returns the maximum number of objects that can be allocated by the pool (checked out to clients, or idle awaiting checkout) at a given time. When non-positive, there is no limit to the number of objects that can be managed by the pool at one time.

Returns:
the cap on the total number of object instances managed by the pool.
See also:
setMaxActive(int)
 
     public synchronized int getMaxActive() {
         return ;
     }

    
Sets the cap on the number of objects that can be allocated by the pool (checked out to clients, or idle awaiting checkout) at a given time. Use a negative value for no limit.

Parameters:
maxActive The cap on the total number of object instances managed by the pool. Negative values mean that there is no limit to the number of objects allocated by the pool.
See also:
getMaxActive()
 
     public void setMaxActive(int maxActive) {
         synchronized(this) {
              = maxActive;
         }
         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).

 
     public synchronized byte getWhenExhaustedAction() {
         return ;
     }

    
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).

Parameters:
whenExhaustedAction the action code, which must be one of WHEN_EXHAUSTED_BLOCK, WHEN_EXHAUSTED_FAIL, or WHEN_EXHAUSTED_GROW
See also:
getWhenExhaustedAction()
 
     public void setWhenExhaustedAction(byte whenExhaustedAction) {
         synchronized(this) {
             switch(whenExhaustedAction) {
                 case :
                 case :
                 case :
                      = 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 WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject() method may block indefinitely.

Returns:
maximum number of milliseconds to block when borrowing an object.
See also:
setMaxWait(long)
setWhenExhaustedAction(byte)
WHEN_EXHAUSTED_BLOCK
 
     public synchronized long getMaxWait() {
         return ;
     }

    
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 WHEN_EXHAUSTED_BLOCK. When less than or equal to 0, the borrowObject() method may block indefinitely.

Parameters:
maxWait maximum number of milliseconds to block when borrowing an object.
See also:
getMaxWait()
setWhenExhaustedAction(byte)
WHEN_EXHAUSTED_BLOCK
 
     public void setMaxWait(long maxWait) {
         synchronized(this) {
              = maxWait;
         }
         allocate();
     }

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

Returns:
the cap on the number of "idle" instances in the pool.
See also:
setMaxIdle(int)
 
     public synchronized int getMaxIdle() {
         return ;
     }

    
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.

Parameters:
maxIdle The cap on the number of "idle" instances in the pool. Use a negative value to indicate an unlimited number of idle instances.
See also:
getMaxIdle()
 
     public void setMaxIdle(int maxIdle) {
         synchronized(this) {
              = maxIdle;
         }
         allocate();
     }

    
Sets the minimum number of objects allowed in the pool before the evictor thread (if active) spawns new objects. Note that no objects are created when numActive + numIdle >= maxActive. This setting has no effect if the idle object evictor is disabled (i.e. if timeBetweenEvictionRunsMillis <= 0).

Parameters:
minIdle The minimum number of objects.
See also:
getMinIdle()
getTimeBetweenEvictionRunsMillis()
 
     public void setMinIdle(int minIdle) {
         synchronized(this) {
              = minIdle;
         }
         allocate();
     }

    
Returns the minimum number of objects allowed in the pool before the evictor thread (if active) spawns new objects. (Note no objects are created when: numActive + numIdle >= maxActive)

Returns:
The minimum number of objects.
See also:
setMinIdle(int)
 
     public synchronized int getMinIdle() {
         return ;
     }

    
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.

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() method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.

Parameters:
testOnBorrow true if objects should be validated before being borrowed.
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).

Returns:
true when objects will be validated after returned to returnObject(java.lang.Object).
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).

Parameters:
testOnReturn true so objects will be validated after returned to returnObject(java.lang.Object).
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:
number of 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 number of milliseconds to sleep between evictor runs.
See also:
getTimeBetweenEvictionRunsMillis()
 
     public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
          = timeBetweenEvictionRunsMillis;
     }

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

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

    
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. That is, when the value is -n, roughly one nth of the idle objects will be tested per run. When the value is positive, the number of tests actually performed in each run will be the minimum of this value and the number of instances idle in the pool.

Parameters:
numTestsPerEvictionRun max number of objects to examine during each evictor 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;
     }

    
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), with the extra condition that at least "minIdle" amount of object remain in the pool.

Returns:
minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
Since:
Pool 1.3
See also:
setSoftMinEvictableIdleTimeMillis(long)
 
     public synchronized long getSoftMinEvictableIdleTimeMillis() {
         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), with the extra condition that at least "minIdle" object instances remain in the pool. When non-positive, no objects will be evicted from the pool due to idle time alone.

Parameters:
softMinEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
Since:
Pool 1.3
See also:
getSoftMinEvictableIdleTimeMillis()
 
     public synchronized void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) {
          = softMinEvictableIdleTimeMillis;
     }

    
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 will be validated by the evictor.
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 will be validated by the evictor.
See also:
getTestWhileIdle()
setTimeBetweenEvictionRunsMillis(long)
 
     public synchronized void setTestWhileIdle(boolean testWhileIdle) {
          = testWhileIdle;
     }

    
Whether or not the idle object pool acts as a LIFO queue. True means that borrowObject returns the most recently used ("last in") idle object in the pool (if there are idle instances available). False means that the pool behaves as a FIFO queue - objects are taken from the idle object pool in the order that they are returned to the pool.

Returns:
true</true> if the pool is configured to act as a LIFO queue
Since:
1.4
 
      public synchronized boolean getLifo() {
          return ;
      }

     
Sets the LIFO property of the pool. True means that borrowObject returns the most recently used ("last in") idle object in the pool (if there are idle instances available). False means that the pool behaves as a FIFO queue - objects are taken from the idle object pool in the order that they are returned to the pool.

Parameters:
lifo the new value for the LIFO property
Since:
1.4
 
      public synchronized void setLifo(boolean lifo) {
         this. = lifo;
     }

    
Sets my configuration.

Parameters:
conf configuration to use.
See also:
GenericObjectPool.Config
    public void setConfig(GenericObjectPool.Config conf) {
        synchronized (this) {
            setMaxIdle(conf.maxIdle);
            setMinIdle(conf.minIdle);
            setMaxActive(conf.maxActive);
            setMaxWait(conf.maxWait);
            setWhenExhaustedAction(conf.whenExhaustedAction);
            setTestOnBorrow(conf.testOnBorrow);
            setTestOnReturn(conf.testOnReturn);
            setTestWhileIdle(conf.testWhileIdle);
            setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
            setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
            setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
            setSoftMinEvictableIdleTimeMillis(conf.softMinEvictableIdleTimeMillis);
            setLifo(conf.lifo);
        }
        allocate();
    }
    //-- ObjectPool methods ------------------------------------------

    

Borrows an object from the pool.

If there is an idle instance available in the pool, 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, behavior depends on the maxActive and (if applicable) whenExhaustedAction and maxWait properties. If the number of instances checked out from the pool is less than maxActive, a new instance is created, activated and (if applicable) validated and returned to the caller.

If the pool is exhausted (no available idle instances and no capacity to create new ones), this method will either block (WHEN_EXHAUSTED_BLOCK), throw a NoSuchElementException (WHEN_EXHAUSTED_FAIL), or grow (WHEN_EXHAUSTED_GROW - ignoring maxActive). 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.

Returns:
object instance
Throws:
java.util.NoSuchElementException if an instance cannot be returned
    @Override
    public T borrowObject() throws Exception {
        long starttime = System.currentTimeMillis();
        Latch<T> latch = new Latch<T>();
        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 = ;
            maxWait = ;
            // Add this request to the queue
            .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 from the pool above
            if(latch.getPair() == null) {
                // check if we were allowed to create one
                if(latch.mayCreate()) {
                    // allow new object to be created
                } else {
                    // the pool is exhausted
                    switch(whenExhaustedAction) {
                        case :
                            // 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()) {
                                    .remove(latch);
                                    ++;
                                }
                            }
                            break;
                        case :
                            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;
                                }
                                .remove(latch);
                            }
                            throw new NoSuchElementException("Pool exhausted");
                        case :
                            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
                                        .remove(latch);
                                    } else if (latch.getPair() == null && latch.mayCreate()) {
                                        // Case 2: latch has been given permission to create
                                        //         a new object
                                        --;
                                        doAllocate = true;
                                    } else {
                                        // Case 3: An object has been allocated
                                        --;
                                        ++;
                                        returnObject(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()) {
                                        // Remove latch from the allocation queue
                                        .remove(latch);
                                    } else {
                                        break;
                                    }
                                }
                                throw new NoSuchElementException("Timeout waiting for idle object");
                            } else {
                                continue// keep looping
                            }
                        default:
                            throw new IllegalArgumentException("WhenExhaustedAction property " + whenExhaustedAction +
                                    " not recognized.");
                    }
                }
            }
            boolean newlyCreated = false;
            if(null == latch.getPair()) {
                try {
                    T obj = .makeObject();
                    latch.setPair(new ObjectTimestampPair<T>(obj));
                    newlyCreated = true;
                } finally {
                    if (!newlyCreated) {
                        // object cannot be created
                        synchronized (this) {
                            --;
                            // No need to reset latch - about to throw exception
                        }
                        allocate();
                    }
                }
            }
            // activate & validate the object
            try {
                .activateObject(latch.getPair().);
                if( &&
                        !.validateObject(latch.getPair().)) {
                    throw new Exception("ValidateObject failed");
                }
                synchronized(this) {
                    --;
                    ++;
                }
                return latch.getPair().;
            }
            catch (Throwable e) {
                PoolUtils.checkRethrow(e);
                // object cannot be activated or is invalid
                try {
                    .destroyObject(latch.getPair().);
                } catch (Throwable e2) {
                    PoolUtils.checkRethrow(e2);
                    // cannot destroy broken object
                }
                synchronized (this) {
                    --;
                    if (!newlyCreated) {
                        latch.reset();
                        .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. While it is safe for GOP, for consistency with GKOP this method should not be called from inside a sync block.
    private synchronized void allocate() {
        if (isClosed()) return;
        // First use any objects in the pool to clear the queue
        for (;;) {
            if (!.isEmpty() && !.isEmpty()) {
                Latch<T> latch = .removeFirst();
                latch.setPair.removeFirst());
                ++;
                synchronized (latch) {
                    latch.notify();
                }
            } else {
                break;
            }
        }
        // Second utilise any spare capacity to create new objects
        for(;;) {
            if((!.isEmpty()) && ( < 0 || ( + ) < )) {
                Latch<T> latch = .removeFirst();
                latch.setMayCreate(true);
                ++;
                synchronized (latch) {
                    latch.notify();
                }
            } else {
                break;
            }
        }
    }

    

Activation of this method decrements the active count and attempts to destroy the instance.

Throws:
java.lang.Exception if the configured org.apache.commons.pool.PoolableObjectFactory throws an exception destroying obj
    @Override
    public void invalidateObject(T objthrows Exception {
        try {
            if ( != null) {
                .destroyObject(obj);
            }
        } finally {
            synchronized (this) {
                --;
            }
            allocate();
        }
    }

    
Clears any objects sitting idle in the pool by removing them from the idle instance pool and then invoking the configured org.apache.commons.pool.PoolableObjectFactory.destroyObject(java.lang.Object) method on each idle instance.

Implementation notes:

  • This method does not destroy or effect in any way instances that are checked out of the pool 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.
    @Override
    public void clear() {
        List<ObjectTimestampPair<T>> toDestroy = new ArrayList<ObjectTimestampPair<T>>();
        synchronized(this) {
            toDestroy.addAll();
            .clear();
        }
        destroy(toDestroy);
    }

    
Private method to destroy all the objects in a collection using the supplied object factory. Assumes that objects in the collection are instances of ObjectTimestampPair and that the object instances that they wrap were created by the factory.

Parameters:
c Collection of objects to destroy
factory PoolableConnectionFactory used to destroy the objects
    private void destroy(Collection<ObjectTimestampPair<T>> cPoolableObjectFactory<T> factory) {
        for (Iterator<ObjectTimestampPair<T>> it = c.iterator(); it.hasNext();) {
            try {
                factory.destroyObject(it.next().);
            } catch(Exception e) {
                // ignore error, keep destroying the rest
            } finally {
                synchronized(this) {
                    --;
                }
                allocate();
            }
        }
    }

    
Return the number of instances currently borrowed from this pool.

Returns:
the number of instances currently borrowed from this pool
    @Override
    public synchronized int getNumActive() {
        return ;
    }

    
Return the number of instances currently idle in this pool.

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

    

Returns an object instance to the pool.

If maxIdle is set to a positive value and the number of idle instances 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. In this case, if validation fails, the instance is destroyed.

Note: There is no guard to prevent an object being returned to the pool multiple times. Clients are expected to discard references to returned objects and ensure that an object is not returned to the pool multiple times in sequence (i.e., without being borrowed again between returns). Violating this contract will result in the same object appearing multiple times in the pool and pool counters (numActive, numIdle) returning incorrect values.

Parameters:
obj instance to return to the pool
    @Override
    public void returnObject(T objthrows Exception {
        try {
            addObjectToPool(objtrue);
        } catch (Exception e) {
            if ( != null) {
                try {
                    .destroyObject(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.
                synchronized(this) {
                    --;
                }
                allocate();
            }
        }
    }

    

Adds an object to the 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

Parameters:
obj instance to add to the pool
decrementNumActive whether or not to decrement the active count
Throws:
java.lang.Exception
    private void addObjectToPool(T objboolean decrementNumActivethrows Exception {
        boolean success = true;
        if( && !(.validateObject(obj))) {
            success = false;
        } else {
            .passivateObject(obj);
        }
        boolean shouldDestroy = !success;
        // Add instance to pool if there is room and it has passed validation
        // (if testOnreturn is set)
        boolean doAllocate = false;
        synchronized (this) {
            if (isClosed()) {
                shouldDestroy = true;
            } else {
                if(( >= 0) && (.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 () {
                        .addFirst(new ObjectTimestampPair<T>(obj));
                    } else {
                        .addLast(new ObjectTimestampPair<T>(obj));
                    }
                    if (decrementNumActive) {
                        --;
                    }
                    doAllocate = true;
                }
            }
        }
        if (doAllocate) {
            allocate();
        }
        // Destroy the instance if necessary
        if(shouldDestroy) {
            try {
                .destroyObject(obj);
            } catch(Exception e) {
                // ignored
            }
            // Decrement active count *after* destroy if applicable
            if (decrementNumActive) {
                synchronized(this) {
                    --;
                }
                allocate();
            }
        }
    }

    

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

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

    @Override
    public void close() throws Exception {
        super.close();
        synchronized (this) {
            clear();
            startEvictor(-1L);
            while(.size() > 0) {
                Latch<T> l = .removeFirst();
                
                synchronized (l) {
                    // notify the waiting thread
                    l.notify();
                }
            }
        }
    }

    
Sets the factory this pool uses to create new instances. Trying to change the factory while there are borrowed objects will throw an java.lang.IllegalStateException. If there are instances idle in the pool when this method is invoked, these will be destroyed using the original factory.

Deprecated:
to be removed in version 2.0
Parameters:
factory the org.apache.commons.pool.PoolableObjectFactory used to create new instances.
Throws:
java.lang.IllegalStateException when the factory cannot be set at this time
    @Override
    public void setFactory(PoolableObjectFactory<T> factorythrows IllegalStateException {
        List<ObjectTimestampPair<T>> toDestroy = new ArrayList<ObjectTimestampPair<T>>();
        final PoolableObjectFactory<T> oldFactory = ;
        synchronized (this) {
            assertOpen();
            if(0 < getNumActive()) {
                throw new IllegalStateException("Objects are already active");
            } else {
                toDestroy.addAll();
                 =  + .;
                .clear();
            }
             = factory;
        }
        destroy(toDestroyoldFactory); 
    }

    

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 in sequence, cycling through objects in oldest-to-youngest order.

Throws:
java.lang.Exception if the pool is closed or eviction fails.
    public void evict() throws Exception {
        assertOpen();
        synchronized (this) {
            if(.isEmpty()) {
                return;
            }
            if (null == ) {
                 = .cursor( ? .size() : 0);
            }
        }
        for (int i=0,m=getNumTests();i<m;i++) {
            final ObjectTimestampPair<T> pair;
            synchronized (this) {
                if (( && !.hasPrevious()) ||
                        ! && !.hasNext()) {
                    .close();
                     = .cursor( ? .size() : 0);
                }
                pair =  ?
                         .previous() :
                         .next();
                .remove();
                ++;
            }
            boolean removeObject = false;
            final long idleTimeMilis = System.currentTimeMillis() - pair.tstamp;
            if ((getMinEvictableIdleTimeMillis() > 0) &&
                    (idleTimeMilis > getMinEvictableIdleTimeMillis())) {
                removeObject = true;
            } else if ((getSoftMinEvictableIdleTimeMillis() > 0) &&
                    (idleTimeMilis > getSoftMinEvictableIdleTimeMillis()) &&
                    ((getNumIdle() + 1)> getMinIdle())) { // +1 accounts for object we are processing
                removeObject = true;
            }
            if(getTestWhileIdle() && !removeObject) {
                boolean active = false;
                try {
                    .activateObject(pair.value);
                    active = true;
                } catch(Exception e) {
                    removeObject=true;
                }
                if(active) {
                    if(!.validateObject(pair.value)) {
                        removeObject=true;
                    } else {
                        try {
                            .passivateObject(pair.value);
                        } catch(Exception e) {
                            removeObject=true;
                        }
                    }
                }
            }
            if (removeObject) {
                try {
                    .destroyObject(pair.value);
                } catch(Exception e) {
                    // ignored
                }
            }
            synchronized (this) {
                if(!removeObject) {
                    .add(pair);
                    if () {
                        // Skip over the element we just added back
                        .previous();
                    }
                }
                --;
            }
        }
        allocate();
    }

    
Check to see if we are below our minimum number of objects if so enough to bring us back to our minimum.

Throws:
java.lang.Exception when addObject() fails.
    private void ensureMinIdle() throws Exception {
        // 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(false);
        for ( int j = 0 ; j < objectDeficit && calculateDeficit(true) > 0 ; j++ ) {
            try {
                addObject();
            } finally {
                synchronized (this) {
                    --;
                }
                allocate();
            }
        }
    }

    
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.

Parameters:
incrementInternal - Should the count of objects currently under some form of internal processing be incremented?
Returns:
The number of objects to be created
    private synchronized int calculateDeficit(boolean incrementInternal) {
        int objectDeficit = getMinIdle() - getNumIdle();
        if ( > 0) {
            int growLimit = Math.max(0,
                    getMaxActive() - getNumActive() - getNumIdle() - );
            objectDeficit = Math.min(objectDeficitgrowLimit);
        }
        if (incrementInternal && objectDeficit >0) {
            ++;
        }
        return objectDeficit;
    }

    
Create an object, and place it into the pool. addObject() is useful for "pre-loading" a pool with idle objects.
    @Override
    public void addObject() throws Exception {
        assertOpen();
        if ( == null) {
            throw new IllegalStateException("Cannot add objects without a factory.");
        }
        T obj = .makeObject();
        try {
            assertOpen();
            addObjectToPool(objfalse);
        } catch (IllegalStateException ex) { // Pool closed
            try {
                .destroyObject(obj);
            } catch (Exception ex2) {
                // swallow
            }
            throw ex;
        }
    }
    //--- 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;
        }
        if(delay > 0) {
             = new Evictor();
            EvictionTimer.schedule(delaydelay);
        }
    }

    
Returns pool info including getNumActive(), getNumIdle() and a list of objects idle in the pool with their idle times.

Returns:
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");
        buf.append("Idle Objects:\n");
        Iterator<ObjectTimestampPair<T>> it = .iterator();
        long time = System.currentTimeMillis();
        while(it.hasNext()) {
            ObjectTimestampPair<T> pair = it.next();
            buf.append("\t").append(pair.value).append("\t").append(time - pair.tstamp).append("\n");
        }
        return buf.toString();
    }

    
Returns the number of tests to be performed in an Evictor run, based on the current value of numTestsPerEvictionRun and the number of idle instances in the pool.

Returns:
the number of tests for the Evictor to run
See also:
setNumTestsPerEvictionRun(int)
    private int getNumTests() {
        if( >= 0) {
            return Math.min(.size());
        } else {
            return(int)(Math.ceil(.size()/Math.abs((double))));
        }
    }
    //--- inner classes ----------------------------------------------

    
    private class Evictor extends TimerTask {
        
Run pool maintenance. Evict objects qualifying for eviction and then invoke GenericObjectPool.ensureMinIdle().
        @Override
        public void run() {
            try {
                evict();