View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.pool.impl;
19  
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.LinkedList;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.NoSuchElementException;
28  import java.util.Set;
29  import java.util.TreeMap;
30  import java.util.TimerTask;
31  import java.util.Map.Entry;
32  
33  import org.apache.commons.pool.BaseKeyedObjectPool;
34  import org.apache.commons.pool.KeyedObjectPool;
35  import org.apache.commons.pool.KeyedPoolableObjectFactory;
36  import org.apache.commons.pool.PoolUtils;
37  
38  /**
39   * A configurable <code>KeyedObjectPool</code> implementation.
40   * <p>
41   * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
42   * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
43   * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map
44   * of pools, keyed on the (unique) key values provided to the
45   * {@link #preparePool preparePool}, {@link #addObject addObject} or
46   * {@link #borrowObject borrowObject} methods. Each time a new key value is
47   * provided to one of these methods, a new pool is created under the given key
48   * to be managed by the containing <code>GenericKeyedObjectPool.</code>
49   * </p>
50   * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable
51   * parameters:</p>
52   * <ul>
53   *  <li>
54   *    {@link #setMaxActive maxActive} controls the maximum number of objects
55   *    (per key) that can allocated by the pool (checked out to client threads,
56   *    or idle in the pool) at one time.  When non-positive, there is no limit
57   *    to the number of objects per key. When {@link #setMaxActive maxActive} is
58   *    reached, the keyed pool is said to be exhausted.  The default setting for
59   *    this parameter is 8.
60   *  </li>
61   *  <li>
62   *    {@link #setMaxTotal maxTotal} sets a global limit on the number of objects
63   *    that can be in circulation (active or idle) within the combined set of
64   *    pools.  When non-positive, there is no limit to the total number of
65   *    objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded,
66   *    all keyed pools are exhausted. When <code>maxTotal</code> is set to a
67   *    positive value and {@link #borrowObject borrowObject} is invoked
68   *    when at the limit with no idle instances available, an attempt is made to
69   *    create room by clearing the oldest 15% of the elements from the keyed
70   *    pools. The default setting for this parameter is -1 (no limit).
71   *  </li>
72   *  <li>
73   *    {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
74   *    sit idle in the pool (per key) at any time.  When negative, there
75   *    is no limit to the number of objects that may be idle per key. The
76   *    default setting for this parameter is 8.
77   *  </li>
78   *  <li>
79   *    {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
80   *    behavior of the {@link #borrowObject borrowObject} method when a keyed
81   *    pool is exhausted:
82   *    <ul>
83   *    <li>
84   *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
85   *      {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
86   *      a {@link NoSuchElementException}
87   *    </li>
88   *    <li>
89   *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
90   *      {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
91   *      object and return it (essentially making {@link #setMaxActive maxActive}
92   *      meaningless.)
93   *    </li>
94   *    <li>
95   *      When {@link #setWhenExhaustedAction whenExhaustedAction}
96   *      is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
97   *      (invoke {@link Object#wait() wait} until a new or idle object is available.
98   *      If a positive {@link #setMaxWait maxWait}
99   *      value is supplied, the {@link #borrowObject borrowObject} will block for at
100  *      most that many milliseconds, after which a {@link NoSuchElementException}
101  *      will be thrown.  If {@link #setMaxWait maxWait} is non-positive,
102  *      the {@link #borrowObject borrowObject} method will block indefinitely.
103  *    </li>
104  *    </ul>
105  *    The default <code>whenExhaustedAction</code> setting is
106  *    {@link #WHEN_EXHAUSTED_BLOCK}.
107  *  </li>
108  *  <li>
109  *    When {@link #setTestOnBorrow testOnBorrow} is set, the pool will
110  *    attempt to validate each object before it is returned from the
111  *    {@link #borrowObject borrowObject} method. (Using the provided factory's
112  *    {@link KeyedPoolableObjectFactory#validateObject validateObject} method.)
113  *    Objects that fail to validate will be dropped from the pool, and a
114  *    different object will be borrowed. The default setting for this parameter
115  *    is <code>false.</code>
116  *  </li>
117  *  <li>
118  *    When {@link #setTestOnReturn testOnReturn} is set, the pool will
119  *    attempt to validate each object before it is returned to the pool in the
120  *    {@link #returnObject returnObject} method. (Using the provided factory's
121  *    {@link KeyedPoolableObjectFactory#validateObject validateObject}
122  *    method.)  Objects that fail to validate will be dropped from the pool.
123  *    The default setting for this parameter is <code>false.</code>
124  *  </li>
125  * </ul>
126  * <p>
127  * Optionally, one may configure the pool to examine and possibly evict objects
128  * as they sit idle in the pool and to ensure that a minimum number of idle
129  * objects is maintained for each key. This is performed by an
130  * "idle object eviction" thread, which runs asynchronously. Caution should be
131  * used when configuring this optional feature. Eviction runs contend with client
132  * threads for access to objects in the pool, so if they run too frequently
133  * performance issues may result.  The idle object eviction thread may be
134  * configured using the following attributes:
135  * <ul>
136  *  <li>
137  *   {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis}
138  *   indicates how long the eviction thread should sleep before "runs" of examining
139  *   idle objects.  When non-positive, no eviction thread will be launched. The
140  *   default setting for this parameter is -1 (i.e., by default, idle object
141  *   eviction is disabled).
142  *  </li>
143  *  <li>
144  *   {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis}
145  *   specifies the minimum amount of time that an object may sit idle in the
146  *   pool before it is eligible for eviction due to idle time.  When
147  *   non-positive, no object will be dropped from the pool due to idle time
148  *   alone.  This setting has no effect unless
149  *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
150  *   for this parameter is 30 minutes.
151  *  </li>
152  *  <li>
153  *   {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle
154  *   objects should be validated using the factory's
155  *   {@link KeyedPoolableObjectFactory#validateObject validateObject} method
156  *   during idle object eviction runs.  Objects that fail to validate will be
157  *   dropped from the pool. This setting has no effect unless
158  *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
159  *   for this parameter is <code>false.</code>
160  *  </li>
161  *  <li>
162  *    {@link #setMinIdle minIdle} sets a target value for the minimum number of
163  *    idle objects (per key) that should always be available. If this parameter
164  *    is set to a positive number and
165  *    <code>timeBetweenEvictionRunsMillis > 0,</code> each time the idle object
166  *    eviction thread runs, it will try to create enough idle instances so that
167  *    there will be <code>minIdle</code> idle instances available under each
168  *    key. This parameter is also used by {@link #preparePool preparePool}
169  *    if <code>true</code> is provided as that method's
170  *    <code>populateImmediately</code> parameter. The default setting for this
171  *    parameter is 0.
172  *  </li>
173  * </ul>
174  * <p>
175  * The pools can be configured to behave as LIFO queues with respect to idle
176  * objects - always returning the most recently used object from the pool,
177  * or as FIFO queues, where borrowObject always returns the oldest object
178  * in the idle object pool.
179  * <ul>
180  *  <li>
181  *   {@link #setLifo <i>Lifo</i>}
182  *   determines whether or not the pools return idle objects in
183  *   last-in-first-out order. The default setting for this parameter is
184  *   <code>true.</code>
185  *  </li>
186  * </ul>
187  * <p>
188  * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}.  A
189  * non-<code>null</code> factory must be provided either as a constructor argument
190  * or via a call to {@link #setFactory setFactory} before the pool is used.
191  * </p>
192  * <p>
193  * Implementation note: To prevent possible deadlocks, care has been taken to
194  * ensure that no call to a factory method will occur within a synchronization
195  * block. See POOL-125 and DBCP-44 for more information.
196  * </p>
197  * @see GenericObjectPool
198  * @author Rodney Waldhoff
199  * @author Dirk Verbeeck
200  * @author Sandy McArthur
201  * @version $Revision: 1206500 $ $Date: 2011-11-26 10:09:06 -0700 (Sat, 26 Nov 2011) $
202  * @since Pool 1.0
203  */
204 public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
205 
206     //--- public constants -------------------------------------------
207 
208     /**
209      * A "when exhausted action" type indicating that when the pool is
210      * exhausted (i.e., the maximum number of active objects has
211      * been reached), the {@link #borrowObject}
212      * method should fail, throwing a {@link NoSuchElementException}.
213      * @see #WHEN_EXHAUSTED_BLOCK
214      * @see #WHEN_EXHAUSTED_GROW
215      * @see #setWhenExhaustedAction
216      */
217     public static final byte WHEN_EXHAUSTED_FAIL   = 0;
218 
219     /**
220      * A "when exhausted action" type indicating that when the pool
221      * is exhausted (i.e., the maximum number
222      * of active objects has been reached), the {@link #borrowObject}
223      * method should block until a new object is available, or the
224      * {@link #getMaxWait maximum wait time} has been reached.
225      * @see #WHEN_EXHAUSTED_FAIL
226      * @see #WHEN_EXHAUSTED_GROW
227      * @see #setMaxWait
228      * @see #getMaxWait
229      * @see #setWhenExhaustedAction
230      */
231     public static final byte WHEN_EXHAUSTED_BLOCK  = 1;
232 
233     /**
234      * A "when exhausted action" type indicating that when the pool is
235      * exhausted (i.e., the maximum number
236      * of active objects has been reached), the {@link #borrowObject}
237      * method should simply create a new object anyway.
238      * @see #WHEN_EXHAUSTED_FAIL
239      * @see #WHEN_EXHAUSTED_GROW
240      * @see #setWhenExhaustedAction
241      */
242     public static final byte WHEN_EXHAUSTED_GROW   = 2;
243 
244     /**
245      * The default cap on the number of idle instances (per key) in the pool.
246      * @see #getMaxIdle
247      * @see #setMaxIdle
248      */
249     public static final int DEFAULT_MAX_IDLE  = 8;
250 
251     /**
252      * The default cap on the total number of active instances (per key)
253      * from the pool.
254      * @see #getMaxActive
255      * @see #setMaxActive
256      */
257     public static final int DEFAULT_MAX_ACTIVE  = 8;
258 
259     /**
260      * The default cap on the the overall maximum number of objects that can
261      * exist at one time.
262      * @see #getMaxTotal
263      * @see #setMaxTotal
264      */
265     public static final int DEFAULT_MAX_TOTAL  = -1;
266 
267     /**
268      * The default "when exhausted action" for the pool.
269      * @see #WHEN_EXHAUSTED_BLOCK
270      * @see #WHEN_EXHAUSTED_FAIL
271      * @see #WHEN_EXHAUSTED_GROW
272      * @see #setWhenExhaustedAction
273      */
274     public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
275 
276     /**
277      * The default maximum amount of time (in milliseconds) the
278      * {@link #borrowObject} method should block before throwing
279      * an exception when the pool is exhausted and the
280      * {@link #getWhenExhaustedAction "when exhausted" action} is
281      * {@link #WHEN_EXHAUSTED_BLOCK}.
282      * @see #getMaxWait
283      * @see #setMaxWait
284      */
285     public static final long DEFAULT_MAX_WAIT = -1L;
286 
287     /**
288      * The default "test on borrow" value.
289      * @see #getTestOnBorrow
290      * @see #setTestOnBorrow
291      */
292     public static final boolean DEFAULT_TEST_ON_BORROW = false;
293 
294     /**
295      * The default "test on return" value.
296      * @see #getTestOnReturn
297      * @see #setTestOnReturn
298      */
299     public static final boolean DEFAULT_TEST_ON_RETURN = false;
300 
301     /**
302      * The default "test while idle" value.
303      * @see #getTestWhileIdle
304      * @see #setTestWhileIdle
305      * @see #getTimeBetweenEvictionRunsMillis
306      * @see #setTimeBetweenEvictionRunsMillis
307      */
308     public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
309 
310     /**
311      * The default "time between eviction runs" value.
312      * @see #getTimeBetweenEvictionRunsMillis
313      * @see #setTimeBetweenEvictionRunsMillis
314      */
315     public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
316 
317     /**
318      * The default number of objects to examine per run in the
319      * idle object evictor.
320      * @see #getNumTestsPerEvictionRun
321      * @see #setNumTestsPerEvictionRun
322      * @see #getTimeBetweenEvictionRunsMillis
323      * @see #setTimeBetweenEvictionRunsMillis
324      */
325     public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
326 
327     /**
328      * The default value for {@link #getMinEvictableIdleTimeMillis}.
329      * @see #getMinEvictableIdleTimeMillis
330      * @see #setMinEvictableIdleTimeMillis
331      */
332     public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
333 
334     /**
335      * The default minimum level of idle objects in the pool.
336      * @since Pool 1.3
337      * @see #setMinIdle
338      * @see #getMinIdle
339      */
340     public static final int DEFAULT_MIN_IDLE = 0;
341 
342     /**
343      * The default LIFO status. True means that borrowObject returns the
344      * most recently used ("last in") idle object in a pool (if there are
345      * idle instances available).  False means that pools behave as FIFO
346      * queues - objects are taken from idle object pools in the order that
347      * they are returned.
348      * @see #setLifo
349      */
350     public static final boolean DEFAULT_LIFO = true;
351 
352     //--- constructors -----------------------------------------------
353 
354     /**
355      * Create a new <code>GenericKeyedObjectPool</code> with no factory.
356      *
357      * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory)
358      * @see #setFactory(KeyedPoolableObjectFactory)
359      */
360     public GenericKeyedObjectPool() {
361         this(null, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, 
362                 DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
363                 DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
364     }
365 
366     /**
367      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
368      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy
369      * objects if not <code>null</code>
370      */
371     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
372         this(factory, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE,
373                 DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
374                 DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
375     }
376 
377     /**
378      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
379      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
380      * if not <code>null</code>
381      * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration
382      */
383     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
384         this(factory, config.maxActive, config.whenExhaustedAction, config.maxWait, config.maxIdle, config.maxTotal,
385                 config.minIdle, config.testOnBorrow, config.testOnReturn, config.timeBetweenEvictionRunsMillis,
386                 config.numTestsPerEvictionRun, config.minEvictableIdleTimeMillis, config.testWhileIdle, config.lifo);
387     }
388 
389     /**
390      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
391      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
392      * if not <code>null</code>
393      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
394      */
395     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
396         this(factory,maxActive, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE,
397                 DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 
398                 DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
399     }
400 
401     /**
402      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
403      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
404      * if not <code>null</code>
405      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
406      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
407      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
408      *  <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
409      */
410     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
411             long maxWait) {
412         this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW,
413                 DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
414                 DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
415     }
416 
417     /**
418      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
419      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
420      * if not <code>null</code>
421      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
422      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
423      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
424      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
425      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
426      * method (see {@link #setTestOnBorrow})
427      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
428      * method (see {@link #setTestOnReturn})
429      */
430     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
431             long maxWait, boolean testOnBorrow, boolean testOnReturn) {
432         this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn,
433                 DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
434                 DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
435     }
436 
437     /**
438      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
439      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
440      * if not <code>null</code>
441      * @param maxActive the maximum number of objects that can be borrowed from me at one time
442      * (see {@link #setMaxActive})
443      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
444      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
445      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
446      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
447      */
448     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
449             long maxWait, int maxIdle) {
450         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN,
451                 DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
452                 DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
453     }
454 
455     /**
456      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
457      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
458      * if not <code>null</code>
459      * @param maxActive the maximum number of objects that can be borrowed from me at one time
460      * (see {@link #setMaxActive})
461      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
462      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
463      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
464      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
465      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
466      * method (see {@link #setTestOnBorrow})
467      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
468      * method (see {@link #setTestOnReturn})
469      */
470     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
471             long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
472         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, testOnBorrow, testOnReturn,
473                 DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
474                 DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
475     }
476 
477     /**
478      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
479      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
480      * if not <code>null</code>
481      * @param maxActive the maximum number of objects that can be borrowed from me at one time
482      * (see {@link #setMaxActive})
483      * @param whenExhaustedAction the action to take when the pool is exhausted 
484      * (see {@link #setWhenExhaustedAction})
485      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
486      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
487      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
488      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
489      * method (see {@link #setTestOnBorrow})
490      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
491      * method (see {@link #setTestOnReturn})
492      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
493      * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
494      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
495      * thread (if any) (see {@link #setNumTestsPerEvictionRun})
496      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
497      * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
498      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
499      * (see {@link #setTestWhileIdle})
500      */
501     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
502             long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis,
503             int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
504         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,
505                 testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
506                 minEvictableIdleTimeMillis, testWhileIdle);
507     }
508 
509     /**
510      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
511      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
512      * if not <code>null</code>
513      * @param maxActive the maximum number of objects that can be borrowed from me at one time
514      * (see {@link #setMaxActive})
515      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
516      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
517      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
518      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
519      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
520      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
521      * method (see {@link #setTestOnBorrow})
522      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
523      * method (see {@link #setTestOnReturn})
524      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
525      * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
526      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
527      * thread (if any) (see {@link #setNumTestsPerEvictionRun})
528      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool
529      * before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
530      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
531      * (see {@link #setTestWhileIdle})
532      */
533     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
534             long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn,
535             long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
536             boolean testWhileIdle) {
537         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal,
538                 GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis,
539                 numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
540     }
541 
542     /**
543      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
544      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
545      * if not <code>null</code>
546      * @param maxActive the maximum number of objects that can be borrowed at one time (see {@link #setMaxActive})
547      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
548      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
549      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
550      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
551      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
552      * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
553      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
554      * method (see {@link #setTestOnBorrow})
555      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
556      * method (see {@link #setTestOnReturn})
557      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
558      * objects
559      * for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
560      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
561      * thread (if any) (see {@link #setNumTestsPerEvictionRun})
562      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
563      * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
564      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
565      * (see {@link #setTestWhileIdle})
566      * @since Pool 1.3
567      */
568     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
569             long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn,
570             long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
571             boolean testWhileIdle) {
572         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn,
573                 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle,
574                 DEFAULT_LIFO);
575     }
576 
577     /**
578      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
579      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
580      * if not <code>null</code>
581      * @param maxActive the maximum number of objects that can be borrowed at one time
582      *  (see {@link #setMaxActive})
583      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
584      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
585      * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
586      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
587      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
588      * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
589      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
590      * method (see {@link #setTestOnBorrow})
591      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
592      * method (see {@link #setTestOnReturn})
593      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
594      * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
595      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
596      * thread (if any) (see {@link #setNumTestsPerEvictionRun})
597      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
598      * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
599      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
600      * (see {@link #setTestWhileIdle})
601      * @param lifo whether or not the pools behave as LIFO (last in first out) queues (see {@link #setLifo})
602      * @since Pool 1.4
603      */
604     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
605             long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn,
606             long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
607             boolean testWhileIdle, boolean lifo) {
608         _factory = factory;
609         _maxActive = maxActive;
610         _lifo = lifo;
611         switch (whenExhaustedAction) {
612             case WHEN_EXHAUSTED_BLOCK:
613             case WHEN_EXHAUSTED_FAIL:
614             case WHEN_EXHAUSTED_GROW:
615                 _whenExhaustedAction = whenExhaustedAction;
616                 break;
617             default:
618                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
619         }
620         _maxWait = maxWait;
621         _maxIdle = maxIdle;
622         _maxTotal = maxTotal;
623         _minIdle = minIdle;
624         _testOnBorrow = testOnBorrow;
625         _testOnReturn = testOnReturn;
626         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
627         _numTestsPerEvictionRun = numTestsPerEvictionRun;
628         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
629         _testWhileIdle = testWhileIdle;
630 
631         _poolMap = new HashMap();
632         _poolList = new CursorableLinkedList();
633 
634         startEvictor(_timeBetweenEvictionRunsMillis);
635     }
636 
637     //--- public methods ---------------------------------------------
638 
639     //--- configuration methods --------------------------------------
640 
641     /**
642      * Returns the cap on the number of object instances allocated by the pool
643      * (checked out or idle),  per key.
644      * A negative value indicates no limit.
645      *
646      * @return the cap on the number of active instances per key.
647      * @see #setMaxActive
648      */
649     public synchronized int getMaxActive() {
650         return _maxActive;
651     }
652 
653     /**
654      * Sets the cap on the number of object instances managed by the pool per key.
655      * @param maxActive The cap on the number of object instances per key.
656      * Use a negative value for no limit.
657      *
658      * @see #getMaxActive
659      */
660     public void setMaxActive(int maxActive) {
661         synchronized(this) {
662             _maxActive = maxActive;
663         }
664         allocate();
665     }
666 
667     /**
668      * Returns the overall maximum number of objects (across pools) that can
669      * exist at one time. A negative value indicates no limit.
670      * @return the maximum number of instances in circulation at one time.
671      * @see #setMaxTotal
672      */
673     public synchronized int getMaxTotal() {
674         return _maxTotal;
675     }
676 
677     /**
678      * Sets the cap on the total number of instances from all pools combined.
679      * When <code>maxTotal</code> is set to a
680      * positive value and {@link #borrowObject borrowObject} is invoked
681      * when at the limit with no idle instances available, an attempt is made to
682      * create room by clearing the oldest 15% of the elements from the keyed
683      * pools.
684      *
685      * @param maxTotal The cap on the total number of instances across pools.
686      * Use a negative value for no limit.
687      * @see #getMaxTotal
688      */
689     public void setMaxTotal(int maxTotal) {
690         synchronized(this) {
691             _maxTotal = maxTotal;
692         }
693         allocate();
694     }
695 
696     /**
697      * Returns the action to take when the {@link #borrowObject} method
698      * is invoked when the pool is exhausted (the maximum number
699      * of "active" objects has been reached).
700      *
701      * @return one of {@link #WHEN_EXHAUSTED_BLOCK},
702      * {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
703      * @see #setWhenExhaustedAction
704      */
705     public synchronized byte getWhenExhaustedAction() {
706         return _whenExhaustedAction;
707     }
708 
709     /**
710      * Sets the action to take when the {@link #borrowObject} method
711      * is invoked when the pool is exhausted (the maximum number
712      * of "active" objects has been reached).
713      *
714      * @param whenExhaustedAction the action code, which must be one of
715      *        {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
716      *        or {@link #WHEN_EXHAUSTED_GROW}
717      * @see #getWhenExhaustedAction
718      */
719     public void setWhenExhaustedAction(byte whenExhaustedAction) {
720         synchronized(this) {
721             switch(whenExhaustedAction) {
722                 case WHEN_EXHAUSTED_BLOCK:
723                 case WHEN_EXHAUSTED_FAIL:
724                 case WHEN_EXHAUSTED_GROW:
725                     _whenExhaustedAction = whenExhaustedAction;
726                     break;
727                 default:
728                     throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
729             }
730         }
731         allocate();
732     }
733 
734 
735     /**
736      * Returns the maximum amount of time (in milliseconds) the
737      * {@link #borrowObject} method should block before throwing
738      * an exception when the pool is exhausted and the
739      * {@link #setWhenExhaustedAction "when exhausted" action} is
740      * {@link #WHEN_EXHAUSTED_BLOCK}.
741      *
742      * When less than or equal to 0, the {@link #borrowObject} method
743      * may block indefinitely.
744      *
745      * @return the maximum number of milliseconds borrowObject will block.
746      * @see #setMaxWait
747      * @see #setWhenExhaustedAction
748      * @see #WHEN_EXHAUSTED_BLOCK
749      */
750     public synchronized long getMaxWait() {
751         return _maxWait;
752     }
753 
754     /**
755      * Sets the maximum amount of time (in milliseconds) the
756      * {@link #borrowObject} method should block before throwing
757      * an exception when the pool is exhausted and the
758      * {@link #setWhenExhaustedAction "when exhausted" action} is
759      * {@link #WHEN_EXHAUSTED_BLOCK}.
760      *
761      * When less than or equal to 0, the {@link #borrowObject} method
762      * may block indefinitely.
763      *
764      * @param maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely.
765      * @see #getMaxWait
766      * @see #setWhenExhaustedAction
767      * @see #WHEN_EXHAUSTED_BLOCK
768      */
769     public void setMaxWait(long maxWait) {
770         synchronized(this) {
771             _maxWait = maxWait;
772         }
773         allocate();
774     }
775 
776     /**
777      * Returns the cap on the number of "idle" instances per key.
778      * @return the maximum number of "idle" instances that can be held
779      * in a given keyed pool.
780      * @see #setMaxIdle
781      */
782     public synchronized int getMaxIdle() {
783         return _maxIdle;
784     }
785 
786     /**
787      * Sets the cap on the number of "idle" instances in the pool.
788      * If maxIdle is set too low on heavily loaded systems it is possible you
789      * will see objects being destroyed and almost immediately new objects
790      * being created. This is a result of the active threads momentarily
791      * returning objects faster than they are requesting them them, causing the
792      * number of idle objects to rise above maxIdle. The best value for maxIdle
793      * for heavily loaded system will vary but the default is a good starting
794      * point.
795      * @param maxIdle the maximum number of "idle" instances that can be held
796      * in a given keyed pool. Use a negative value for no limit.
797      * @see #getMaxIdle
798      * @see #DEFAULT_MAX_IDLE
799      */
800     public void setMaxIdle(int maxIdle) {
801         synchronized(this) {
802             _maxIdle = maxIdle;
803         }
804         allocate();
805     }
806 
807     /**
808      * Sets the minimum number of idle objects to maintain in each of the keyed
809      * pools. This setting has no effect unless
810      * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
811      * that each pool has the required minimum number of instances are only
812      * made during idle object eviction runs.
813      * @param poolSize - The minimum size of the each keyed pool
814      * @since Pool 1.3
815      * @see #getMinIdle
816      * @see #setTimeBetweenEvictionRunsMillis
817      */
818     public void setMinIdle(int poolSize) {
819         _minIdle = poolSize;
820     }
821 
822     /**
823      * Returns the minimum number of idle objects to maintain in each of the keyed
824      * pools. This setting has no effect unless
825      * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
826      * that each pool has the required minimum number of instances are only
827      * made during idle object eviction runs.
828      * @return minimum size of the each keyed pool
829      * @since Pool 1.3
830      * @see #setTimeBetweenEvictionRunsMillis
831      */
832     public int getMinIdle() {
833         return _minIdle;
834     }
835 
836     /**
837      * When <code>true</code>, objects will be
838      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
839      * before being returned by the {@link #borrowObject}
840      * method.  If the object fails to validate,
841      * it will be dropped from the pool, and we will attempt
842      * to borrow another.
843      *
844      * @return <code>true</code> if objects are validated before being borrowed.
845      * @see #setTestOnBorrow
846      */
847     public boolean getTestOnBorrow() {
848         return _testOnBorrow;
849     }
850 
851     /**
852      * When <code>true</code>, objects will be
853      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
854      * before being returned by the {@link #borrowObject}
855      * method.  If the object fails to validate,
856      * it will be dropped from the pool, and we will attempt
857      * to borrow another.
858      *
859      * @param testOnBorrow whether object should be validated before being returned by borrowObject.
860      * @see #getTestOnBorrow
861      */
862     public void setTestOnBorrow(boolean testOnBorrow) {
863         _testOnBorrow = testOnBorrow;
864     }
865 
866     /**
867      * When <code>true</code>, objects will be
868      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
869      * before being returned to the pool within the
870      * {@link #returnObject}.
871      *
872      * @return <code>true</code> when objects will be validated before being returned.
873      * @see #setTestOnReturn
874      */
875     public boolean getTestOnReturn() {
876         return _testOnReturn;
877     }
878 
879     /**
880      * When <code>true</code>, objects will be
881      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
882      * before being returned to the pool within the
883      * {@link #returnObject}.
884      *
885      * @param testOnReturn <code>true</code> so objects will be validated before being returned.
886      * @see #getTestOnReturn
887      */
888     public void setTestOnReturn(boolean testOnReturn) {
889         _testOnReturn = testOnReturn;
890     }
891 
892     /**
893      * Returns the number of milliseconds to sleep between runs of the
894      * idle object evictor thread.
895      * When non-positive, no idle object evictor thread will be
896      * run.
897      *
898      * @return milliseconds to sleep between evictor runs.
899      * @see #setTimeBetweenEvictionRunsMillis
900      */
901     public synchronized long getTimeBetweenEvictionRunsMillis() {
902         return _timeBetweenEvictionRunsMillis;
903     }
904 
905     /**
906      * Sets the number of milliseconds to sleep between runs of the
907      * idle object evictor thread.
908      * When non-positive, no idle object evictor thread will be
909      * run.
910      *
911      * @param timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs.
912      * @see #getTimeBetweenEvictionRunsMillis
913      */
914     public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
915         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
916         startEvictor(_timeBetweenEvictionRunsMillis);
917     }
918 
919     /**
920      * Returns the max number of objects to examine during each run of the
921      * idle object evictor thread (if any).
922      *
923      * @return number of objects to examine each eviction run.
924      * @see #setNumTestsPerEvictionRun
925      * @see #setTimeBetweenEvictionRunsMillis
926      */
927     public synchronized int getNumTestsPerEvictionRun() {
928         return _numTestsPerEvictionRun;
929     }
930 
931     /**
932      * Sets the max number of objects to examine during each run of the
933      * idle object evictor thread (if any).
934      * <p>
935      * When a negative value is supplied, 
936      * <code>ceil({@link #getNumIdle()})/abs({@link #getNumTestsPerEvictionRun})</code>
937      * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
938      * idle objects will be tested per run.  When the value is positive, the number of tests
939      * actually performed in each run will be the minimum of this value and the number of instances
940      * idle in the pools.
941      *
942      * @param numTestsPerEvictionRun number of objects to examine each eviction run.
943      * @see #setNumTestsPerEvictionRun
944      * @see #setTimeBetweenEvictionRunsMillis
945      */
946     public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
947         _numTestsPerEvictionRun = numTestsPerEvictionRun;
948     }
949 
950     /**
951      * Returns the minimum amount of time an object may sit idle in the pool
952      * before it is eligible for eviction by the idle object evictor
953      * (if any).
954      *
955      * @return minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
956      * @see #setMinEvictableIdleTimeMillis
957      * @see #setTimeBetweenEvictionRunsMillis
958      */
959     public synchronized long getMinEvictableIdleTimeMillis() {
960         return _minEvictableIdleTimeMillis;
961     }
962 
963     /**
964      * Sets the minimum amount of time an object may sit idle in the pool
965      * before it is eligible for eviction by the idle object evictor
966      * (if any).
967      * When non-positive, no objects will be evicted from the pool
968      * due to idle time alone.
969      *
970      * @param minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before
971      * it is eligible for eviction.
972      * @see #getMinEvictableIdleTimeMillis
973      * @see #setTimeBetweenEvictionRunsMillis
974      */
975     public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
976         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
977     }
978 
979     /**
980      * When <code>true</code>, objects will be
981      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
982      * by the idle object evictor (if any).  If an object
983      * fails to validate, it will be dropped from the pool.
984      *
985      * @return <code>true</code> when objects are validated when borrowed.
986      * @see #setTestWhileIdle
987      * @see #setTimeBetweenEvictionRunsMillis
988      */
989     public synchronized boolean getTestWhileIdle() {
990         return _testWhileIdle;
991     }
992 
993     /**
994      * When <code>true</code>, objects will be
995      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
996      * by the idle object evictor (if any).  If an object
997      * fails to validate, it will be dropped from the pool.
998      *
999      * @param testWhileIdle <code>true</code> so objects are validated when borrowed.
1000      * @see #getTestWhileIdle
1001      * @see #setTimeBetweenEvictionRunsMillis
1002      */
1003     public synchronized void setTestWhileIdle(boolean testWhileIdle) {
1004         _testWhileIdle = testWhileIdle;
1005     }
1006 
1007     /**
1008      * Sets the configuration.
1009      * @param conf the new configuration to use.
1010      * @see GenericKeyedObjectPool.Config
1011      */
1012     public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
1013         setMaxIdle(conf.maxIdle);
1014         setMaxActive(conf.maxActive);
1015         setMaxTotal(conf.maxTotal);
1016         setMinIdle(conf.minIdle);
1017         setMaxWait(conf.maxWait);
1018         setWhenExhaustedAction(conf.whenExhaustedAction);
1019         setTestOnBorrow(conf.testOnBorrow);
1020         setTestOnReturn(conf.testOnReturn);
1021         setTestWhileIdle(conf.testWhileIdle);
1022         setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
1023         setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
1024         setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
1025     }
1026 
1027     /**
1028      * Whether or not the idle object pools act as LIFO queues. True means
1029      * that borrowObject returns the most recently used ("last in") idle object
1030      * in a pool (if there are idle instances available).  False means that
1031      * the pools behave as FIFO queues - objects are taken from idle object
1032      * pools in the order that they are returned.
1033      *
1034      * @return <code>true</code> if the pools are configured to act as LIFO queues
1035      * @since 1.4
1036      */
1037      public synchronized boolean getLifo() {
1038          return _lifo;
1039      }
1040 
1041      /**
1042       * Sets the LIFO property of the pools. True means that borrowObject returns
1043       * the most recently used ("last in") idle object in a pool (if there are
1044       * idle instances available).  False means that the pools behave as FIFO
1045       * queues - objects are taken from idle object pools in the order that
1046       * they are returned.
1047       *
1048       * @param lifo the new value for the lifo property
1049       * @since 1.4
1050       */
1051      public synchronized void setLifo(boolean lifo) {
1052          this._lifo = lifo;
1053      }
1054 
1055     //-- ObjectPool methods ------------------------------------------
1056 
1057     /**
1058      * <p>Borrows an object from the keyed pool associated with the given key.</p>
1059      * 
1060      * <p>If there is an idle instance available in the pool associated with the given key, then
1061      * either the most-recently returned (if {@link #getLifo() lifo} == true) or "oldest" (lifo == false)
1062      * instance sitting idle in the pool will be activated and returned.  If activation fails, or
1063      * {@link #getTestOnBorrow() testOnBorrow} is set to true and validation fails, the instance is destroyed and the
1064      * next available instance is examined.  This continues until either a valid instance is returned or there
1065      * are no more idle instances available.</p>
1066      * 
1067      * <p>If there are no idle instances available in the pool associated with the given key, behavior
1068      * depends on the {@link #getMaxActive() maxActive}, {@link #getMaxTotal() maxTotal}, and (if applicable)
1069      * {@link #getWhenExhaustedAction() whenExhaustedAction} and {@link #getMaxWait() maxWait} properties. If the
1070      * number of instances checked out from the pool under the given key is less than <code>maxActive</code> and
1071      * the total number of instances in circulation (under all keys) is less than <code>maxTotal</code>, a new instance
1072      * is created, activated and (if applicable) validated and returned to the caller.</p>
1073      * 
1074      * <p>If the associated keyed pool is exhausted (no available idle instances and no capacity to create new ones),
1075      * this method will either block ({@link #WHEN_EXHAUSTED_BLOCK}), throw a <code>NoSuchElementException</code>
1076      * ({@link #WHEN_EXHAUSTED_FAIL}), or grow ({@link #WHEN_EXHAUSTED_GROW} - ignoring maxActive, maxTotal properties).
1077      * The length of time that this method will block when <code>whenExhaustedAction == WHEN_EXHAUSTED_BLOCK</code>
1078      * is determined by the {@link #getMaxWait() maxWait} property.</p>
1079      * 
1080      * <p>When the pool is exhausted, multiple calling threads may be simultaneously blocked waiting for instances
1081      * to become available.  As of pool 1.5, a "fairness" algorithm has been implemented to ensure that threads receive
1082      * available instances in request arrival order.</p>
1083      * 
1084      * @param key pool key
1085      * @return object instance from the keyed pool
1086      * @throws NoSuchElementException if a keyed object instance cannot be returned.
1087      */
1088      public Object borrowObject(Object key) throws Exception {
1089         long starttime = System.currentTimeMillis();
1090         Latch latch = new Latch(key);
1091         byte whenExhaustedAction;
1092         long maxWait;
1093         synchronized (this) {
1094             // Get local copy of current config. Can't sync when used later as
1095             // it can result in a deadlock. Has the added advantage that config
1096             // is consistent for entire method execution
1097             whenExhaustedAction = _whenExhaustedAction;
1098             maxWait = _maxWait;
1099 
1100             // Add this request to the queue
1101             _allocationQueue.add(latch);
1102         }
1103         // Work the allocation queue, allocating idle instances and
1104         // instance creation permits in request arrival order
1105         allocate();
1106 
1107         for(;;) {
1108             synchronized (this) {
1109                 assertOpen();
1110             }
1111             // If no object was allocated
1112             if (null == latch.getPair()) {
1113                 // Check to see if we were allowed to create one
1114                 if (latch.mayCreate()) {
1115                     // allow new object to be created
1116                 } else {
1117                     // the pool is exhausted
1118                     switch(whenExhaustedAction) {
1119                         case WHEN_EXHAUSTED_GROW:
1120                             // allow new object to be created
1121                             synchronized (this) {
1122                                 // Make sure another thread didn't allocate us an object
1123                                 // or permit a new object to be created
1124                                 if (latch.getPair() == null && !latch.mayCreate()) {
1125                                     _allocationQueue.remove(latch);
1126                                     latch.getPool().incrementInternalProcessingCount();
1127                                 }
1128                             }
1129                         break;
1130                         case WHEN_EXHAUSTED_FAIL:
1131                             synchronized (this) {
1132                                 // Make sure allocate hasn't already assigned an object
1133                                 // in a different thread or permitted a new object to be created
1134                                 if (latch.getPair() != null || latch.mayCreate()) {
1135                                     break;
1136                                 }
1137                                 _allocationQueue.remove(latch);
1138                             }
1139                             throw new NoSuchElementException("Pool exhausted");
1140                         case WHEN_EXHAUSTED_BLOCK:
1141                             try {
1142                                 synchronized (latch) {
1143                                     // Before we wait, make sure another thread didn't allocate us an object
1144                                     // or permit a new object to be created
1145                                     if (latch.getPair() == null && !latch.mayCreate()) {
1146                                         if (maxWait <= 0) {
1147                                             latch.wait();
1148                                         } else {
1149                                             // this code may be executed again after a notify then continue cycle
1150                                             // so, need to calculate the amount of time to wait
1151                                             final long elapsed = (System.currentTimeMillis() - starttime);
1152                                             final long waitTime = maxWait - elapsed;
1153                                             if (waitTime > 0)
1154                                             {
1155                                                 latch.wait(waitTime);
1156                                             }
1157                                         }
1158                                     } else {
1159                                         break;
1160                                     }
1161                                 }
1162                                 // see if we were awakened by a closing pool
1163                                 if(isClosed() == true) {
1164                                     throw new IllegalStateException("Pool closed");
1165                                 }
1166                             } catch(InterruptedException e) {
1167                                 boolean doAllocate = false;
1168                                 synchronized (this) {
1169                                     // Need to handle the all three possibilities
1170                                     if (latch.getPair() == null && !latch.mayCreate()) {
1171                                         // Case 1: latch still in allocation queue
1172                                         // Remove latch from the allocation queue
1173                                         _allocationQueue.remove(latch);
1174                                     } else if (latch.getPair() == null && latch.mayCreate()) {
1175                                         // Case 2: latch has been given permission to create
1176                                         //         a new object
1177                                         latch.getPool().decrementInternalProcessingCount();
1178                                         doAllocate = true;
1179                                     } else {
1180                                         // Case 3: An object has been allocated
1181                                         latch.getPool().decrementInternalProcessingCount();
1182                                         latch.getPool().incrementActiveCount();
1183                                         returnObject(latch.getkey(), latch.getPair().getValue());
1184                                     }
1185                                 }
1186                                 if (doAllocate) {
1187                                     allocate();
1188                                 }
1189                                 Thread.currentThread().interrupt();
1190                                 throw e;
1191                             }
1192                             if (maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) {
1193                                 synchronized (this) {
1194                                     // Make sure allocate hasn't already assigned an object
1195                                     // in a different thread or permitted a new object to be created
1196                                     if (latch.getPair() == null && !latch.mayCreate()) {
1197                                         _allocationQueue.remove(latch);
1198                                     } else {
1199                                         break;
1200                                     }
1201                                 }
1202                                 throw new NoSuchElementException("Timeout waiting for idle object");
1203                             } else {
1204                                 continue; // keep looping
1205                             }
1206                         default:
1207                             throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction +
1208                                     " not recognized.");
1209                     }
1210                 }
1211             }
1212 
1213             boolean newlyCreated = false;
1214             if (null == latch.getPair()) {
1215                 try {
1216                     Object obj = _factory.makeObject(key);
1217                     latch.setPair(new ObjectTimestampPair(obj));
1218                     newlyCreated = true;
1219                 } finally {
1220                     if (!newlyCreated) {
1221                         // object cannot be created
1222                         synchronized (this) {
1223                             latch.getPool().decrementInternalProcessingCount();
1224                             // No need to reset latch - about to throw exception
1225                         }
1226                         allocate();
1227                     }
1228                 }
1229             }
1230 
1231             // activate & validate the object
1232             try {
1233                 _factory.activateObject(key, latch.getPair().value);
1234                 if (_testOnBorrow && !_factory.validateObject(key, latch.getPair().value)) {
1235                     throw new Exception("ValidateObject failed");
1236                 }
1237                 synchronized (this) {
1238                     latch.getPool().decrementInternalProcessingCount();
1239                     latch.getPool().incrementActiveCount();
1240                 }
1241                 return latch.getPair().value;
1242             } catch (Throwable e) {
1243                 PoolUtils.checkRethrow(e);
1244                 // object cannot be activated or is invalid
1245                 try {
1246                     _factory.destroyObject(key, latch.getPair().value);
1247                 } catch (Throwable e2) {
1248                     PoolUtils.checkRethrow(e2);
1249                     // cannot destroy broken object
1250                 }
1251                 synchronized (this) {
1252                     latch.getPool().decrementInternalProcessingCount();
1253                     if (!newlyCreated) {
1254                         latch.reset();
1255                         _allocationQueue.add(0, latch);
1256                     }
1257                 }
1258                 allocate();
1259                 if (newlyCreated) {
1260                     throw new NoSuchElementException(
1261                        "Could not create a validated object, cause: " +
1262                             e.getMessage());
1263                 }
1264                 else {
1265                     continue; // keep looping
1266                 }
1267             }
1268         }
1269     }
1270 
1271     /**
1272      * Allocate available instances to latches in the allocation queue.  Then
1273      * set _mayCreate to true for as many additional latches remaining in queue
1274      * as _maxActive allows for each key. This method <b>MUST NOT</b> be called
1275      * from inside a sync block.
1276      */
1277     private void allocate() {
1278         boolean clearOldest = false;
1279 
1280         synchronized (this) {
1281             if (isClosed()) return;
1282             
1283             Iterator allocationQueueIter = _allocationQueue.iterator();
1284             
1285             while (allocationQueueIter.hasNext()) {
1286                 // First use any objects in the pool to clear the queue
1287                 Latch latch = (Latch) allocationQueueIter.next();
1288                 ObjectQueue pool = (ObjectQueue)(_poolMap.get(latch.getkey()));
1289                 if (null == pool) {
1290                     pool = new ObjectQueue();
1291                     _poolMap.put(latch.getkey(), pool);
1292                     _poolList.add(latch.getkey());
1293                 }
1294                 latch.setPool(pool);
1295                 if (!pool.queue.isEmpty()) {
1296                     allocationQueueIter.remove();
1297                     latch.setPair(
1298                             (ObjectTimestampPair) pool.queue.removeFirst());
1299                     pool.incrementInternalProcessingCount();
1300                     _totalIdle--;
1301                     synchronized (latch) {
1302                         latch.notify();
1303                     }
1304                     // Next item in queue
1305                     continue;
1306                 }
1307 
1308                 // If there is a totalMaxActive and we are at the limit then
1309                 // we have to make room
1310                 if ((_maxTotal > 0) &&
1311                         (_totalActive + _totalIdle + _totalInternalProcessing >= _maxTotal)) {
1312                     clearOldest = true;
1313                     break;
1314                 }
1315 
1316                 // Second utilise any spare capacity to create new objects
1317                 if ((_maxActive < 0 || pool.activeCount + pool.internalProcessingCount < _maxActive) &&
1318                         (_maxTotal < 0 || _totalActive + _totalIdle + _totalInternalProcessing < _maxTotal)) {
1319                     // allow new object to be created
1320                     allocationQueueIter.remove();
1321                     latch.setMayCreate(true);
1322                     pool.incrementInternalProcessingCount();
1323                     synchronized (latch) {
1324                         latch.notify();
1325                     }
1326                     // Next item in queue
1327                     continue;
1328                 }
1329 
1330                 // If there is no per-key limit and we reach this point we
1331                 // must have allocated all the objects we possibly can and there
1332                 // is no point looking at the rest of the allocation queue
1333                 if (_maxActive < 0) {
1334                     break;
1335                 }
1336             }
1337         }
1338         
1339         if (clearOldest) {
1340             /* Clear oldest calls factory methods so it must be called from
1341              * outside the sync block.
1342              * It also needs to be outside the sync block as it calls
1343              * allocate(). If called inside the sync block, the call to
1344              * allocate() would be able to enter the sync block (since the
1345              * thread already has the lock) which may have unexpected,
1346              * unpleasant results.
1347              */
1348             clearOldest();
1349         }
1350     }
1351     
1352     /**
1353      * Clears any objects sitting idle in the pool by removing them from the
1354      * idle instance pool and then invoking the configured PoolableObjectFactory's
1355      * {@link KeyedPoolableObjectFactory#destroyObject(Object, Object)} method on
1356      * each idle instance.
1357      *  
1358      * <p> Implementation notes:
1359      * <ul><li>This method does not destroy or effect in any way instances that are
1360      * checked out when it is invoked.</li>
1361      * <li>Invoking this method does not prevent objects being
1362      * returned to the idle instance pool, even during its execution. It locks
1363      * the pool only during instance removal. Additional instances may be returned
1364      * while removed items are being destroyed.</li>
1365      * <li>Exceptions encountered destroying idle instances are swallowed.</li></ul></p>
1366      */
1367     public void clear() {
1368         Map toDestroy = new HashMap();
1369         synchronized (this) {
1370             for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
1371                 Object key = it.next();
1372                 ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
1373                 // Copy objects to new list so pool.queue can be cleared inside
1374                 // the sync
1375                 List objects = new ArrayList();
1376                 objects.addAll(pool.queue);
1377                 toDestroy.put(key, objects);
1378                 it.remove();
1379                 _poolList.remove(key);
1380                 _totalIdle = _totalIdle - pool.queue.size();
1381                 _totalInternalProcessing =
1382                     _totalInternalProcessing + pool.queue.size();
1383                 pool.queue.clear();
1384             }
1385         }
1386         destroy(toDestroy, _factory);
1387     }
1388 
1389     /**
1390      * Clears oldest 15% of objects in pool.  The method sorts the
1391      * objects into a TreeMap and then iterates the first 15% for removal.
1392      * 
1393      * @since Pool 1.3
1394      */
1395     public void clearOldest() {
1396         // Map of objects to destroy my key
1397         final Map toDestroy = new HashMap();
1398 
1399         // build sorted map of idle objects
1400         final Map map = new TreeMap();
1401         synchronized (this) {
1402             for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
1403                 final Object key = keyiter.next();
1404                 final CursorableLinkedList list = ((ObjectQueue)_poolMap.get(key)).queue;
1405                 for (Iterator it = list.iterator(); it.hasNext();) {
1406                     // each item into the map uses the objectimestamppair object
1407                     // as the key.  It then gets sorted based on the timstamp field
1408                     // each value in the map is the parent list it belongs in.
1409                     map.put(it.next(), key);
1410                 }
1411             }
1412 
1413             // Now iterate created map and kill the first 15% plus one to account for zero
1414             Set setPairKeys = map.entrySet();
1415             int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
1416 
1417             Iterator iter = setPairKeys.iterator();
1418             while (iter.hasNext() && itemsToRemove > 0) {
1419                 Map.Entry entry = (Map.Entry) iter.next();
1420                 // kind of backwards on naming.  In the map, each key is the objecttimestamppair
1421                 // because it has the ordering with the timestamp value.  Each value that the
1422                 // key references is the key of the list it belongs to.
1423                 Object key = entry.getValue();
1424                 ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
1425                 ObjectQueue objectQueue = (ObjectQueue)_poolMap.get(key);
1426                 final CursorableLinkedList list = objectQueue.queue;
1427                 list.remove(pairTimeStamp);
1428 
1429                 if (toDestroy.containsKey(key)) {
1430                     ((List)toDestroy.get(key)).add(pairTimeStamp);
1431                 } else {
1432                     List listForKey = new ArrayList();
1433                     listForKey.add(pairTimeStamp);
1434                     toDestroy.put(key, listForKey);
1435                 }
1436                 objectQueue.incrementInternalProcessingCount();
1437                 _totalIdle--;
1438                 itemsToRemove--;
1439             }
1440 
1441         }
1442         destroy(toDestroy, _factory);
1443     }
1444 
1445     /**
1446      * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
1447      *
1448      * @param key the key to clear
1449      */
1450     public void clear(Object key) {
1451         Map toDestroy = new HashMap();
1452 
1453         final ObjectQueue pool;
1454         synchronized (this) {
1455             pool = (ObjectQueue)(_poolMap.remove(key));
1456             if (pool == null) {
1457                 return;
1458             } else {
1459                 _poolList.remove(key);
1460             }
1461             // Copy objects to new list so pool.queue can be cleared inside
1462             // the sync
1463             List objects = new ArrayList();
1464             objects.addAll(pool.queue);
1465             toDestroy.put(key, objects);
1466             _totalIdle = _totalIdle - pool.queue.size();
1467             _totalInternalProcessing =
1468                 _totalInternalProcessing + pool.queue.size();
1469             pool.queue.clear();
1470         }
1471         destroy(toDestroy, _factory);
1472     }
1473 
1474     /**
1475      * Assuming Map<Object,Collection<ObjectTimestampPair>>, destroy all
1476      * ObjectTimestampPair.value using the supplied factory.
1477      * 
1478      * @param m Map containing keyed pools to clear
1479      * @param factory KeyedPoolableObjectFactory used to destroy the objects
1480      */
1481     private void destroy(Map m, KeyedPoolableObjectFactory factory) {
1482         for (Iterator entries = m.entrySet().iterator(); entries.hasNext();) {
1483             Map.Entry entry = (Entry) entries.next();
1484             Object key = entry.getKey();
1485             Collection c = (Collection) entry.getValue();
1486             for (Iterator it = c.iterator(); it.hasNext();) {
1487                 try {
1488                     factory.destroyObject(
1489                             key,((ObjectTimestampPair)(it.next())).value);
1490                 } catch(Exception e) {
1491                     // ignore error, keep destroying the rest
1492                 } finally {
1493                     synchronized(this) {
1494                         ObjectQueue objectQueue =
1495                                 (ObjectQueue) _poolMap.get(key);
1496                         if (objectQueue != null) {
1497                             objectQueue.decrementInternalProcessingCount();
1498                             if (objectQueue.internalProcessingCount == 0 &&
1499                                     objectQueue.activeCount == 0 &&
1500                                     objectQueue.queue.isEmpty()) {
1501                                 _poolMap.remove(key);
1502                                 _poolList.remove(key);
1503                             }
1504                         } else {
1505                             _totalInternalProcessing--;
1506                         }
1507                     }
1508                     allocate();
1509                 }
1510             }
1511 
1512         }
1513     }
1514 
1515     /**
1516      * Returns the total number of instances current borrowed from this pool but not yet returned.
1517      *
1518      * @return the total number of instances currently borrowed from this pool
1519      */
1520     public synchronized int getNumActive() {
1521         return _totalActive;
1522     }
1523 
1524     /**
1525      * Returns the total number of instances currently idle in this pool.
1526      *
1527      * @return the total number of instances currently idle in this pool
1528      */
1529     public synchronized int getNumIdle() {
1530         return _totalIdle;
1531     }
1532 
1533     /**
1534      * Returns the number of instances currently borrowed from but not yet returned
1535      * to the pool corresponding to the given <code>key</code>.
1536      *
1537      * @param key the key to query
1538      * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
1539      */
1540     public synchronized int getNumActive(Object key) {
1541         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1542         return pool != null ? pool.activeCount : 0;
1543     }
1544 
1545     /**
1546      * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
1547      *
1548      * @param key the key to query
1549      * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
1550      */
1551     public synchronized int getNumIdle(Object key) {
1552         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1553         return pool != null ? pool.queue.size() : 0;
1554     }
1555 
1556     /**
1557      * <p>Returns an object to a keyed pool.</p>
1558      * 
1559      * <p>For the pool to function correctly, the object instance <strong>must</strong> have been borrowed
1560      * from the pool (under the same key) and not yet returned. Repeated <code>returnObject</code> calls on
1561      * the same object/key pair (with no <code>borrowObject</code> calls in between) will result in multiple
1562      * references to the object in the idle instance pool.</p>
1563      * 
1564      * <p>If {@link #getMaxIdle() maxIdle} is set to a positive value and the number of idle instances under the given
1565      * key has reached this value, the returning instance is destroyed.</p>
1566      * 
1567      * <p>If {@link #getTestOnReturn() testOnReturn} == true, the returning instance is validated before being returned
1568      * to the idle instance pool under the given key.  In this case, if validation fails, the instance is destroyed.</p>
1569      * 
1570      * @param key pool key
1571      * @param obj instance to return to the keyed pool
1572      * @throws Exception
1573      */
1574     public void returnObject(Object key, Object obj) throws Exception {
1575         try {
1576             addObjectToPool(key, obj, true);
1577         } catch (Exception e) {
1578             if (_factory != null) {
1579                 try {
1580                     _factory.destroyObject(key, obj);
1581                 } catch (Exception e2) {
1582                     // swallowed
1583                 }
1584                 // TODO: Correctness here depends on control in addObjectToPool.
1585                 // These two methods should be refactored, removing the
1586                 // "behavior flag", decrementNumActive, from addObjectToPool.
1587                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1588                 if (pool != null) {
1589                     synchronized(this) {
1590                         pool.decrementActiveCount();
1591                         if (pool.queue.isEmpty() &&
1592                                 pool.activeCount == 0 &&
1593                                 pool.internalProcessingCount == 0) {
1594                             _poolMap.remove(key);
1595                             _poolList.remove(key);
1596                         }
1597                     }
1598                     allocate();
1599                 }
1600             }
1601         }
1602     }
1603 
1604     /**
1605      * <p>Adds an object to the keyed pool.</p>
1606      * 
1607      * <p>Validates the object if testOnReturn == true and passivates it before returning it to the pool.
1608      * if validation or passivation fails, or maxIdle is set and there is no room in the pool, the instance
1609      * is destroyed.</p>
1610      * 
1611      * <p>Calls {@link #allocate()} on successful completion</p>
1612      * 
1613      * @param key pool key
1614      * @param obj instance to add to the keyed pool
1615      * @param decrementNumActive whether or not to decrement the active count associated with the keyed pool
1616      * @throws Exception
1617      */
1618     private void addObjectToPool(Object key, Object obj,
1619             boolean decrementNumActive) throws Exception {
1620 
1621         // if we need to validate this object, do so
1622         boolean success = true; // whether or not this object passed validation
1623         if (_testOnReturn && !_factory.validateObject(key, obj)) {
1624             success = false;
1625         } else {
1626             _factory.passivateObject(key, obj);
1627         }
1628 
1629         boolean shouldDestroy = !success;
1630         ObjectQueue pool;
1631 
1632         // Add instance to pool if there is room and it has passed validation
1633         // (if testOnreturn is set)
1634         boolean doAllocate = false;
1635         synchronized (this) {
1636             // grab the pool (list) of objects associated with the given key
1637             pool = (ObjectQueue) (_poolMap.get(key));
1638             // if it doesn't exist, create it
1639             if (null == pool) {
1640                 pool = new ObjectQueue();
1641                 _poolMap.put(key, pool);
1642                 _poolList.add(key);
1643             }
1644             if (isClosed()) {
1645                 shouldDestroy = true;
1646             } else {
1647                 // if there's no space in the pool, flag the object for destruction
1648                 // else if we passivated successfully, return it to the pool
1649                 if (_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) {
1650                     shouldDestroy = true;
1651                 } else if (success) {
1652                     // borrowObject always takes the first element from the queue,
1653                     // so for LIFO, push on top, FIFO add to end
1654                     if (_lifo) {
1655                         pool.queue.addFirst(new ObjectTimestampPair(obj));
1656                     } else {
1657                         pool.queue.addLast(new ObjectTimestampPair(obj));
1658                     }
1659                     _totalIdle++;
1660                     if (decrementNumActive) {
1661                         pool.decrementActiveCount();
1662                     }
1663                     doAllocate = true;
1664                 }
1665             }
1666         }
1667         if (doAllocate) {
1668             allocate();
1669         }
1670 
1671         // Destroy the instance if necessary
1672         if (shouldDestroy) {
1673             try {
1674                 _factory.destroyObject(key, obj);
1675             } catch(Exception e) {
1676                 // ignored?
1677             }
1678             // Decrement active count *after* destroy if applicable
1679             if (decrementNumActive) {
1680                 synchronized(this) {
1681                     pool.decrementActiveCount();
1682                     if (pool.queue.isEmpty() &&
1683                             pool.activeCount == 0 &&
1684                             pool.internalProcessingCount == 0) {
1685                         _poolMap.remove(key);
1686                         _poolList.remove(key);
1687                     }
1688                 }
1689                 allocate();
1690             }
1691         }
1692     }
1693 
1694     /**
1695      * {@inheritDoc}
1696      * <p>Activation of this method decrements the active count associated with the given keyed pool 
1697      * and attempts to destroy <code>obj.</code></p>
1698      * 
1699      * @param key pool key
1700      * @param obj instance to invalidate
1701      * @throws Exception if an exception occurs destroying the object
1702      */
1703     public void invalidateObject(Object key, Object obj) throws Exception {
1704         try {
1705             _factory.destroyObject(key, obj);
1706         } finally {
1707             synchronized (this) {
1708                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1709                 if (null == pool) {
1710                     pool = new ObjectQueue();
1711                     _poolMap.put(key, pool);
1712                     _poolList.add(key);
1713                 }
1714                 pool.decrementActiveCount();
1715             }
1716             allocate(); // _totalActive has changed
1717         }
1718     }
1719 
1720     /**
1721      * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
1722      * passivate it, and then place it in the idle object pool.
1723      * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
1724      *
1725      * @param key the key a new instance should be added to
1726      * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
1727      * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been
1728      * called on this pool.
1729      */
1730     public void addObject(Object key) throws Exception {
1731         assertOpen();
1732         if (_factory == null) {
1733             throw new IllegalStateException("Cannot add objects without a factory.");
1734         }
1735         Object obj = _factory.makeObject(key);
1736         try {
1737             assertOpen();
1738             addObjectToPool(key, obj, false);
1739         } catch (IllegalStateException ex) { // Pool closed
1740             try {
1741                 _factory.destroyObject(key, obj);
1742             } catch (Exception ex2) {
1743                 // swallow
1744             }
1745             throw ex;
1746         }
1747     }
1748 
1749     /**
1750      * Registers a key for pool control.
1751      *
1752      * If <code>populateImmediately</code> is <code>true</code> and
1753      * <code>minIdle > 0,</code> the pool under the given key will be
1754      * populated immediately with <code>minIdle</code> idle instances.
1755      *
1756      * @param key - The key to register for pool control.
1757      * @param populateImmediately - If this is <code>true</code>, the pool
1758      * will be populated immediately.
1759      * @since Pool 1.3
1760      */
1761     public synchronized void preparePool(Object key, boolean populateImmediately) {
1762         ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1763         if (null == pool) {
1764             pool = new ObjectQueue();
1765             _poolMap.put(key,pool);
1766             _poolList.add(key);
1767         }
1768 
1769         if (populateImmediately) {
1770             try {
1771                 // Create the pooled objects
1772                 ensureMinIdle(key);
1773             }
1774             catch (Exception e) {
1775                 //Do nothing
1776             }
1777         }
1778     }
1779 
1780     /**
1781      * <p>Closes the keyed object pool.  Once the pool is closed, {@link #borrowObject(Object)}
1782      * will fail with IllegalStateException, but {@link #returnObject(Object, Object)} and
1783      * {@link #invalidateObject(Object, Object)} will continue to work, with returned objects
1784      * destroyed on return.</p>
1785      * 
1786      * <p>Destroys idle instances in the pool by invoking {@link #clear()}.</p> 
1787      * 
1788      * @throws Exception
1789      */
1790     public void close() throws Exception {
1791         super.close();
1792         synchronized (this) {
1793             clear();
1794             if (null != _evictionCursor) {
1795                 _evictionCursor.close();
1796                 _evictionCursor = null;
1797             }
1798             if (null != _evictionKeyCursor) {
1799                 _evictionKeyCursor.close();
1800                 _evictionKeyCursor = null;
1801             }
1802             startEvictor(-1L);
1803             
1804             while(_allocationQueue.size() > 0) {
1805                 Latch l = (Latch) _allocationQueue.removeFirst();
1806                 
1807                 synchronized (l) {
1808                     // notify the waiting thread
1809                     l.notify();
1810                 }
1811             }
1812         }
1813     }
1814 
1815     /**
1816      * <p>Sets the keyed poolable object factory associated with this pool.</p>
1817      * 
1818      * <p>If this method is called when objects are checked out of any of the keyed pools,
1819      * an IllegalStateException is thrown.  Calling this method also has the side effect of
1820      * destroying any idle instances in existing keyed pools, using the original factory.</p>
1821      * 
1822      * @param factory KeyedPoolableObjectFactory to use when creating keyed object pool instances
1823      * @throws IllegalStateException if there are active (checked out) instances associated with this keyed object pool
1824      * @deprecated to be removed in version 2.0
1825      */
1826     public void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
1827         Map toDestroy = new HashMap();
1828         final KeyedPoolableObjectFactory oldFactory = _factory;
1829         synchronized (this) {
1830             assertOpen();
1831             if (0 < getNumActive()) {
1832                 throw new IllegalStateException("Objects are already active");
1833             } else {
1834                 for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
1835                     Object key = it.next();
1836                     ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
1837                     if (pool != null) {
1838                         // Copy objects to new list so pool.queue can be cleared
1839                         // inside the sync
1840                         List objects = new ArrayList();
1841                         objects.addAll(pool.queue);
1842                         toDestroy.put(key, objects);
1843                         it.remove();
1844                         _poolList.remove(key);
1845                         _totalIdle = _totalIdle - pool.queue.size();
1846                         _totalInternalProcessing =
1847                             _totalInternalProcessing + pool.queue.size();
1848                         pool.queue.clear();
1849                     }
1850                 }
1851                 _factory = factory;
1852             }
1853         }
1854         destroy(toDestroy, oldFactory);
1855     }
1856 
1857     /**
1858      * <p>Perform <code>numTests</code> idle object eviction tests, evicting
1859      * examined objects that meet the criteria for eviction. If
1860      * <code>testWhileIdle</code> is true, examined objects are validated
1861      * when visited (and removed if invalid); otherwise only objects that
1862      * have been idle for more than <code>minEvicableIdletimeMillis</code>
1863      * are removed.</p>
1864      *
1865      * <p>Successive activations of this method examine objects in keyed pools
1866      * in sequence, cycling through the keys and examining objects in
1867      * oldest-to-youngest order within the keyed pools.</p>
1868      *
1869      * @throws Exception when there is a problem evicting idle objects.
1870      */
1871     public void evict() throws Exception {
1872         Object key = null;
1873         boolean testWhileIdle;
1874         long minEvictableIdleTimeMillis;
1875 
1876         synchronized (this) {
1877             // Get local copy of current config. Can't sync when used later as
1878             // it can result in a deadlock. Has the added advantage that config
1879             // is consistent for entire method execution
1880             testWhileIdle = _testWhileIdle;
1881             minEvictableIdleTimeMillis = _minEvictableIdleTimeMillis;
1882 
1883             // Initialize key to last key value
1884             if (_evictionKeyCursor != null &&
1885                     _evictionKeyCursor._lastReturned != null) {
1886                 key = _evictionKeyCursor._lastReturned.value();
1887             }
1888         }
1889 
1890         for (int i=0, m=getNumTests(); i<m; i++) {
1891             final ObjectTimestampPair pair;
1892             synchronized (this) {
1893                 // make sure pool map is not empty; otherwise do nothing
1894                 if (_poolMap == null || _poolMap.size() == 0) {
1895                     continue;
1896                 }
1897 
1898                 // if we don't have a key cursor, then create one
1899                 if (null == _evictionKeyCursor) {
1900                     resetEvictionKeyCursor();
1901                     key = null;
1902                 }
1903 
1904                 // if we don't have an object cursor, create one
1905                 if (null == _evictionCursor) {
1906                     // if the _evictionKeyCursor has a next value, use this key
1907                     if (_evictionKeyCursor.hasNext()) {
1908                         key = _evictionKeyCursor.next();
1909                         resetEvictionObjectCursor(key);
1910                     } else {
1911                         // Reset the key cursor and try again
1912                         resetEvictionKeyCursor();
1913                         if (_evictionKeyCursor != null) {
1914                             if (_evictionKeyCursor.hasNext()) {
1915                                 key = _evictionKeyCursor.next();
1916                                 resetEvictionObjectCursor(key);
1917                             }
1918                         }
1919                     }
1920                 }
1921 
1922                 if (_evictionCursor == null) {
1923                     continue; // should never happen; do nothing
1924                 }
1925 
1926                 // If eviction cursor is exhausted, try to move
1927                 // to the next key and reset
1928                 if ((_lifo && !_evictionCursor.hasPrevious()) ||
1929                         (!_lifo && !_evictionCursor.hasNext())) {
1930                     if (_evictionKeyCursor != null) {
1931                         if (_evictionKeyCursor.hasNext()) {
1932                             key = _evictionKeyCursor.next();
1933                             resetEvictionObjectCursor(key);
1934                         } else { // Need to reset Key cursor
1935                             resetEvictionKeyCursor();
1936                             if (_evictionKeyCursor != null) {
1937                                 if (_evictionKeyCursor.hasNext()) {
1938                                     key = _evictionKeyCursor.next();
1939                                     resetEvictionObjectCursor(key);
1940                                 }
1941                             }
1942                         }
1943                     }
1944                 }
1945 
1946                 if ((_lifo && !_evictionCursor.hasPrevious()) ||
1947                         (!_lifo && !_evictionCursor.hasNext())) {
1948                     continue; // reset failed, do nothing
1949                 }
1950 
1951                 // if LIFO and the _evictionCursor has a previous object,
1952                 // or FIFO and _evictionCursor has a next object, test it
1953                 pair = _lifo ?
1954                         (ObjectTimestampPair) _evictionCursor.previous() :
1955                         (ObjectTimestampPair) _evictionCursor.next();
1956                 _evictionCursor.remove();
1957                 ObjectQueue objectQueue = (ObjectQueue) _poolMap.get(key);
1958                 objectQueue.incrementInternalProcessingCount();
1959                 _totalIdle--;
1960             }
1961 
1962             boolean removeObject=false;
1963             if ((minEvictableIdleTimeMillis > 0) &&
1964                (System.currentTimeMillis() - pair.tstamp >
1965                minEvictableIdleTimeMillis)) {
1966                 removeObject=true;
1967             }
1968             if (testWhileIdle && removeObject == false) {
1969                 boolean active = false;
1970                 try {
1971                     _factory.activateObject(key,pair.value);
1972                     active = true;
1973                 } catch(Exception e) {
1974                     removeObject=true;
1975                 }
1976                 if (active) {
1977                     if (!_factory.validateObject(key,pair.value)) {
1978                         removeObject=true;
1979                     } else {
1980                         try {
1981                             _factory.passivateObject(key,pair.value);
1982                         } catch(Exception e) {
1983                             removeObject=true;
1984                         }
1985                     }
1986                 }
1987             }
1988 
1989             if (removeObject) {
1990                 try {
1991                     _factory.destroyObject(key, pair.value);
1992                 } catch(Exception e) {
1993                     // ignored
1994                 }
1995             }
1996             synchronized (this) {
1997                 ObjectQueue objectQueue =
1998                     (ObjectQueue)_poolMap.get(key);
1999                 objectQueue.decrementInternalProcessingCount();
2000                 if (removeObject) {
2001                     if (objectQueue.queue.isEmpty() &&
2002                             objectQueue.activeCount == 0 &&
2003                             objectQueue.internalProcessingCount == 0) {
2004                         _poolMap.remove(key);
2005                         _poolList.remove(key);
2006                     }
2007                 } else {
2008                     _evictionCursor.add(pair);
2009                     _totalIdle++;
2010                     if (_lifo) {
2011                         // Skip over the element we just added back
2012                         _evictionCursor.previous();
2013                     }
2014                 }
2015             }
2016         }
2017         allocate();
2018     }
2019 
2020     /**
2021      * Resets the eviction key cursor and closes any
2022      * associated eviction object cursor
2023      */
2024     private void resetEvictionKeyCursor() {
2025         if (_evictionKeyCursor != null) {
2026             _evictionKeyCursor.close();
2027         }
2028         _evictionKeyCursor = _poolList.cursor();
2029         if (null != _evictionCursor) {
2030             _evictionCursor.close();
2031             _evictionCursor = null;
2032         }
2033     }
2034 
2035     /**
2036      * Resets the eviction object cursor for the given key
2037      *
2038      * @param key eviction key
2039      */
2040     private void resetEvictionObjectCursor(Object key) {
2041         if (_evictionCursor != null) {
2042             _evictionCursor.close();
2043         }
2044         if (_poolMap == null) {
2045             return;
2046         }
2047         ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
2048         if (pool != null) {
2049             CursorableLinkedList queue = pool.queue;
2050             _evictionCursor = queue.cursor(_lifo ? queue.size() : 0);
2051         }
2052     }
2053 
2054     /**
2055      * Iterates through all the known keys and creates any necessary objects to maintain
2056      * the minimum level of pooled objects.
2057      * @see #getMinIdle
2058      * @see #setMinIdle
2059      * @throws Exception If there was an error whilst creating the pooled objects.
2060      */
2061     private void ensureMinIdle() throws Exception {
2062         //Check if should sustain the pool
2063         if (_minIdle > 0) {
2064             Object[] keysCopy;
2065             synchronized(this) {
2066                 // Get the current set of keys
2067                 keysCopy = _poolMap.keySet().toArray();
2068             }
2069 
2070             // Loop through all elements in _poolList
2071             // Find out the total number of max active and max idle for that class
2072             // If the number is less than the minIdle, do creation loop to boost numbers
2073             for (int i=0; i < keysCopy.length; i++) {
2074                 //Get the next key to process
2075                 ensureMinIdle(keysCopy[i]);
2076             }
2077         }
2078     }
2079 
2080     /**
2081      * Re-creates any needed objects to maintain the minimum levels of
2082      * pooled objects for the specified key.
2083      *
2084      * This method uses {@link #calculateDeficit} to calculate the number
2085      * of objects to be created. {@link #calculateDeficit} can be overridden to
2086      * provide a different method of calculating the number of objects to be
2087      * created.
2088      * @param key The key to process
2089      * @throws Exception If there was an error whilst creating the pooled objects
2090      */
2091     private void ensureMinIdle(Object key) throws Exception {
2092         // Calculate current pool objects
2093         ObjectQueue pool;
2094         synchronized(this) {
2095             pool = (ObjectQueue)(_poolMap.get(key));
2096         }
2097         if (pool == null) {
2098             return;
2099         }
2100 
2101         // this method isn't synchronized so the
2102         // calculateDeficit is done at the beginning
2103         // as a loop limit and a second time inside the loop
2104         // to stop when another thread already returned the
2105         // needed objects
2106         int objectDeficit = calculateDeficit(pool, false);
2107 
2108         for (int i = 0; i < objectDeficit && calculateDeficit(pool, true) > 0; i++) {
2109             try {
2110                 addObject(key);
2111             } finally {
2112                 synchronized (this) {
2113                     pool.decrementInternalProcessingCount();
2114                 }
2115                 allocate();
2116             }
2117         }
2118     }
2119 
2120     //--- non-public methods ----------------------------------------
2121 
2122     /**
2123      * Start the eviction thread or service, or when
2124      * <code>delay</code> is non-positive, stop it
2125      * if it is already running.
2126      *
2127      * @param delay milliseconds between evictor runs.
2128      */
2129     protected synchronized void startEvictor(long delay) {
2130         if (null != _evictor) {
2131             EvictionTimer.cancel(_evictor);
2132             _evictor = null;
2133         }
2134         if (delay > 0) {
2135             _evictor = new Evictor();
2136             EvictionTimer.schedule(_evictor, delay, delay);
2137         }
2138     }
2139 
2140     /**
2141      * Returns pool info including {@link #getNumActive()}, {@link #getNumIdle()}
2142      * and currently defined keys.
2143      * 
2144      * @return string containing debug information
2145      */
2146     synchronized String debugInfo() {
2147         StringBuffer buf = new StringBuffer();
2148         buf.append("Active: ").append(getNumActive()).append("\n");
2149         buf.append("Idle: ").append(getNumIdle()).append("\n");
2150         Iterator it = _poolMap.keySet().iterator();
2151         while (it.hasNext()) {
2152             Object key = it.next();
2153             buf.append("\t").append(key).append(" ").append(_poolMap.get(key)).append("\n");
2154         }
2155         return buf.toString();
2156     }
2157 
2158     /** 
2159      * Returns the number of tests to be performed in an Evictor run,
2160      * based on the current values of <code>_numTestsPerEvictionRun</code>
2161      * and <code>_totalIdle</code>.
2162      * 
2163      * @see #setNumTestsPerEvictionRun
2164      * @return the number of tests for the Evictor to run
2165      */
2166     private synchronized int getNumTests() {
2167         if (_numTestsPerEvictionRun >= 0) {
2168             return Math.min(_numTestsPerEvictionRun, _totalIdle);
2169         } else {
2170             return(int)(Math.ceil(_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
2171         }
2172     }
2173 
2174     /**
2175      * This returns the number of objects to create during the pool
2176      * sustain cycle. This will ensure that the minimum number of idle
2177      * instances is maintained without going past the maxActive value.
2178      * 
2179      * @param pool the ObjectPool to calculate the deficit for
2180      * @param incrementInternal - Should the count of objects currently under
2181      *                            some form of internal processing be
2182      *                            incremented?
2183      * @return The number of objects to be created
2184      */
2185     private synchronized int calculateDeficit(ObjectQueue pool,
2186             boolean incrementInternal) {
2187         int objectDefecit = 0;
2188 
2189         //Calculate no of objects needed to be created, in order to have
2190         //the number of pooled objects < maxActive();
2191         objectDefecit = getMinIdle() - pool.queue.size();
2192         if (getMaxActive() > 0) {
2193             int growLimit = Math.max(0, getMaxActive() - pool.activeCount - pool.queue.size() - pool.internalProcessingCount);
2194             objectDefecit = Math.min(objectDefecit, growLimit);
2195         }
2196 
2197         // Take the maxTotal limit into account
2198         if (getMaxTotal() > 0) {
2199             int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle() - _totalInternalProcessing);
2200             objectDefecit = Math.min(objectDefecit, growLimit);
2201         }
2202 
2203         if (incrementInternal && objectDefecit > 0) {
2204             pool.incrementInternalProcessingCount();
2205         }
2206         return objectDefecit;
2207     }
2208 
2209     //--- inner classes ----------------------------------------------
2210 
2211     /**
2212      * A "struct" that keeps additional information about the actual queue of pooled objects.
2213      */
2214     private class ObjectQueue {
2215         /** Number of instances checked out to clients from this queue */
2216         private int activeCount = 0;
2217         
2218         /** Idle instance queue */
2219         private final CursorableLinkedList queue = new CursorableLinkedList();
2220         
2221         /** Number of instances in process of being created */
2222         private int internalProcessingCount = 0;
2223 
2224         /** Increment the active count for this queue */
2225         void incrementActiveCount() {
2226             synchronized (GenericKeyedObjectPool.this) {
2227                 _totalActive++;
2228             }
2229             activeCount++;
2230         }
2231 
2232         /** Decrement the active count for this queue */
2233         void decrementActiveCount() {
2234             synchronized (GenericKeyedObjectPool.this) {
2235                 _totalActive--;
2236             }
2237             if (activeCount > 0) {
2238                 activeCount--;
2239             }
2240         }
2241 
2242         /** Record the fact that one more instance is queued for creation */
2243         void incrementInternalProcessingCount() {
2244             synchronized (GenericKeyedObjectPool.this) {
2245                 _totalInternalProcessing++;
2246             }
2247             internalProcessingCount++;
2248         }
2249 
2250         /** Decrement the number of instances in process of being created */
2251         void decrementInternalProcessingCount() {
2252             synchronized (GenericKeyedObjectPool.this) {
2253                 _totalInternalProcessing--;
2254             }
2255             internalProcessingCount--;
2256         }
2257     }
2258 
2259     /**
2260      * A simple "struct" encapsulating an object instance and a timestamp.
2261      *
2262      * Implements Comparable, objects are sorted from old to new.
2263      *
2264      * This is also used by {@link GenericObjectPool}.
2265      */
2266     static class ObjectTimestampPair implements Comparable {
2267         //CHECKSTYLE: stop VisibilityModifier
2268         /** 
2269          * Object instance 
2270          * @deprecated this field will be made private and final in version 2.0
2271          */
2272         Object value;
2273         
2274         /**
2275          * timestamp
2276          * @deprecated this field will be made private and final in version 2.0
2277          */
2278         long tstamp;
2279         //CHECKSTYLE: resume VisibilityModifier
2280 
2281         /**
2282          * Create a new ObjectTimestampPair using the given object and the current system time.
2283          * @param val object instance
2284          */
2285         ObjectTimestampPair(Object val) {
2286             this(val, System.currentTimeMillis());
2287         }
2288 
2289         /**
2290          * Create a new ObjectTimeStampPair using the given object and timestamp value.
2291          * @param val object instance
2292          * @param time long representation of timestamp
2293          */
2294         ObjectTimestampPair(Object val, long time) {
2295             value = val;
2296             tstamp = time;
2297         }
2298 
2299         /**
2300          * Returns a string representation.
2301          * 
2302          * @return String representing this ObjectTimestampPair
2303          */
2304         public String toString() {
2305             return value + ";" + tstamp;
2306         }
2307 
2308         /**
2309          * Compares this to another object by casting the argument to an
2310          * ObjectTimestampPair.
2311          * 
2312          * @param obj object to cmpare
2313          * @return result of comparison
2314          */
2315         public int compareTo(Object obj) {
2316             return compareTo((ObjectTimestampPair) obj);
2317         }
2318 
2319         /**
2320          * Compares this to another ObjectTimestampPair, using the timestamp as basis for comparison.
2321          * Implementation is consistent with equals.
2322          * 
2323          * @param other object to compare
2324          * @return result of comparison
2325          */
2326         public int compareTo(ObjectTimestampPair other) {
2327             final long tstampdiff = this.tstamp - other.tstamp;
2328             if (tstampdiff == 0) {
2329                 // make sure the natural ordering is consistent with equals
2330                 // see java.lang.Comparable Javadocs
2331                 return System.identityHashCode(this) - System.identityHashCode(other);
2332             } else {
2333                 // handle int overflow
2334                 return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
2335             }
2336         }
2337 
2338         /**
2339          * @return the value
2340          */
2341         public Object getValue() {
2342             return value;
2343         }
2344 
2345         /**
2346          * @return the tstamp
2347          */
2348         public long getTstamp() {
2349             return tstamp;
2350         }
2351     }
2352 
2353     /**
2354      * The idle object evictor {@link TimerTask}.
2355      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
2356      */
2357     private class Evictor extends TimerTask {
2358         /**
2359          * Run pool maintenance.  Evict objects qualifying for eviction and then
2360          * invoke {@link GenericKeyedObjectPool#ensureMinIdle()}.
2361          */
2362         public void run() {
2363             //Evict from the pool
2364             try {
2365                 evict();
2366             } catch(Exception e) {
2367                 // ignored
2368             } catch(OutOfMemoryError oome) {
2369                 // Log problem but give evictor thread a chance to continue in
2370                 // case error is recoverable
2371                 oome.printStackTrace(System.err);
2372             }
2373             //Re-create idle instances.
2374             try {
2375                 ensureMinIdle();
2376             } catch (Exception e) {
2377                 // ignored
2378             }
2379         }
2380     }
2381 
2382     /**
2383      * A simple "struct" encapsulating the
2384      * configuration information for a <code>GenericKeyedObjectPool</code>.
2385      * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
2386      * @see GenericKeyedObjectPool#setConfig
2387      */
2388     public static class Config {
2389         //CHECKSTYLE: stop VisibilityModifier
2390         /**
2391          * @see GenericKeyedObjectPool#setMaxIdle
2392          */
2393         public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
2394         /**
2395          * @see GenericKeyedObjectPool#setMaxActive
2396          */
2397         public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
2398         /**
2399          * @see GenericKeyedObjectPool#setMaxTotal
2400          */
2401         public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
2402         /**
2403          * @see GenericKeyedObjectPool#setMinIdle
2404          */
2405         public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
2406         /**
2407          * @see GenericKeyedObjectPool#setMaxWait
2408          */
2409         public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
2410         /**
2411          * @see GenericKeyedObjectPool#setWhenExhaustedAction
2412          */
2413         public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
2414         /**
2415          * @see GenericKeyedObjectPool#setTestOnBorrow
2416          */
2417         public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
2418         /**
2419          * @see GenericKeyedObjectPool#setTestOnReturn
2420          */
2421         public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
2422         /**
2423          * @see GenericKeyedObjectPool#setTestWhileIdle
2424          */
2425         public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
2426         /**
2427          * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
2428          */
2429         public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
2430         /**
2431          * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun
2432          */
2433         public int numTestsPerEvictionRun =  GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
2434         /**
2435          * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis
2436          */
2437         public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
2438         /**
2439          * @see GenericKeyedObjectPool#setLifo
2440          */
2441         public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO;
2442         //CHECKSTYLE: resume VisibilityModifier
2443     }
2444 
2445     /**
2446      * Latch used to control allocation order of objects to threads to ensure
2447      * fairness. That is, for each key, objects are allocated to threads in the order
2448      * that threads request objects.
2449      * 
2450      * @since 1.5
2451      */
2452     private static final class Latch {
2453         
2454         /** key of associated pool */
2455         private final Object _key;
2456         
2457         /** keyed pool associated with this latch */
2458         private ObjectQueue _pool;
2459         
2460         /** holds an ObjectTimestampPair when this latch has been allocated an instance */
2461         private ObjectTimestampPair _pair;
2462         
2463         /** indicates that this latch can create an instance */
2464         private boolean _mayCreate = false;
2465 
2466         /**
2467          * Create a latch with the given key
2468          * @param key key of the pool associated with this latch
2469          */
2470         private Latch(Object key) {
2471             _key = key;
2472         }
2473 
2474         /**
2475          * Retuns the key of the associated pool
2476          * @return associated pool key
2477          */
2478         private synchronized Object getkey() {
2479             return _key;
2480         }
2481 
2482         /**
2483          * Returns the pool associated with this latch
2484          * @return pool
2485          */
2486         private synchronized ObjectQueue getPool() {
2487             return _pool;
2488         }
2489         
2490         /**
2491          * Sets the pool associated with this latch
2492          * @param pool the pool
2493          */
2494         private synchronized void setPool(ObjectQueue pool) {
2495             _pool = pool;
2496         }
2497 
2498         /**
2499          * Gets the ObjectTimestampPair allocated to this latch.
2500          * Returns null if this latch does not have an instance allocated to it. 
2501          * @return the associated ObjectTimestampPair
2502          */
2503         private synchronized ObjectTimestampPair getPair() {
2504             return _pair;
2505         }
2506         
2507         /**
2508          * Allocate an ObjectTimestampPair to this latch.
2509          * @param pair ObjectTimestampPair on this latch
2510          */
2511         private synchronized void setPair(ObjectTimestampPair pair) {
2512             _pair = pair;
2513         }
2514 
2515         /**
2516          * Whether or not this latch can create an instance
2517          * @return true if this latch has an instance creation permit
2518          */
2519         private synchronized boolean mayCreate() {
2520             return _mayCreate;
2521         }
2522         
2523         /**
2524          * Sets the mayCreate property
2525          * 
2526          * @param mayCreate true means this latch can create an instance
2527          */
2528         private synchronized void setMayCreate(boolean mayCreate) {
2529             _mayCreate = mayCreate;
2530         }
2531 
2532         /**
2533          * Reset the latch data. Used when an allocation fails and the latch
2534          * needs to be re-added to the queue.
2535          */
2536         private synchronized void reset() {
2537             _pair = null;
2538             _mayCreate = false;
2539         }
2540     }
2541 
2542     //--- protected attributes ---------------------------------------
2543 
2544     /**
2545      * The cap on the number of idle instances in the pool.
2546      * @see #setMaxIdle
2547      * @see #getMaxIdle
2548      */
2549     private int _maxIdle = DEFAULT_MAX_IDLE;
2550 
2551     /**
2552      * The minimum no of idle objects to keep in the pool.
2553      * @see #setMinIdle
2554      * @see #getMinIdle
2555      */
2556     private volatile int _minIdle = DEFAULT_MIN_IDLE;
2557 
2558     /**
2559      * The cap on the number of active instances from the pool.
2560      * @see #setMaxActive
2561      * @see #getMaxActive
2562      */
2563     private int _maxActive = DEFAULT_MAX_ACTIVE;
2564 
2565     /**
2566      * The cap on the total number of instances from the pool if non-positive.
2567      * @see #setMaxTotal
2568      * @see #getMaxTotal
2569      */
2570     private int _maxTotal = DEFAULT_MAX_TOTAL;
2571 
2572     /**
2573      * The maximum amount of time (in millis) the
2574      * {@link #borrowObject} method should block before throwing
2575      * an exception when the pool is exhausted and the
2576      * {@link #getWhenExhaustedAction "when exhausted" action} is
2577      * {@link #WHEN_EXHAUSTED_BLOCK}.
2578      *
2579      * When less than or equal to 0, the {@link #borrowObject} method
2580      * may block indefinitely.
2581      *
2582      * @see #setMaxWait
2583      * @see #getMaxWait
2584      * @see #WHEN_EXHAUSTED_BLOCK
2585      * @see #setWhenExhaustedAction
2586      * @see #getWhenExhaustedAction
2587      */
2588     private long _maxWait = DEFAULT_MAX_WAIT;
2589 
2590     /**
2591      * The action to take when the {@link #borrowObject} method
2592      * is invoked when the pool is exhausted (the maximum number
2593      * of "active" objects has been reached).
2594      *
2595      * @see #WHEN_EXHAUSTED_BLOCK
2596      * @see #WHEN_EXHAUSTED_FAIL
2597      * @see #WHEN_EXHAUSTED_GROW
2598      * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
2599      * @see #setWhenExhaustedAction
2600      * @see #getWhenExhaustedAction
2601      */
2602     private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
2603 
2604     /**
2605      * When <code>true</code>, objects will be
2606      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2607      * before being returned by the {@link #borrowObject}
2608      * method.  If the object fails to validate,
2609      * it will be dropped from the pool, and we will attempt
2610      * to borrow another.
2611      *
2612      * @see #setTestOnBorrow
2613      * @see #getTestOnBorrow
2614      */
2615     private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
2616 
2617     /**
2618      * When <code>true</code>, objects will be
2619      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2620      * before being returned to the pool within the
2621      * {@link #returnObject}.
2622      *
2623      * @see #getTestOnReturn
2624      * @see #setTestOnReturn
2625      */
2626     private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
2627 
2628     /**
2629      * When <code>true</code>, objects will be
2630      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2631      * by the idle object evictor (if any).  If an object
2632      * fails to validate, it will be dropped from the pool.
2633      *
2634      * @see #setTestWhileIdle
2635      * @see #getTestWhileIdle
2636      * @see #getTimeBetweenEvictionRunsMillis
2637      * @see #setTimeBetweenEvictionRunsMillis
2638      */
2639     private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
2640 
2641     /**
2642      * The number of milliseconds to sleep between runs of the
2643      * idle object evictor thread.
2644      * When non-positive, no idle object evictor thread will be
2645      * run.
2646      *
2647      * @see #setTimeBetweenEvictionRunsMillis
2648      * @see #getTimeBetweenEvictionRunsMillis
2649      */
2650     private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
2651 
2652     /**
2653      * The number of objects to examine during each run of the
2654      * idle object evictor thread (if any).
2655      * <p>
2656      * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
2657      * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
2658      * idle objects will be tested per run.
2659      *
2660      * @see #setNumTestsPerEvictionRun
2661      * @see #getNumTestsPerEvictionRun
2662      * @see #getTimeBetweenEvictionRunsMillis
2663      * @see #setTimeBetweenEvictionRunsMillis
2664      */
2665     private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
2666 
2667     /**
2668      * The minimum amount of time an object may sit idle in the pool
2669      * before it is eligible for eviction by the idle object evictor
2670      * (if any).
2671      * When non-positive, no objects will be evicted from the pool
2672      * due to idle time alone.
2673      *
2674      * @see #setMinEvictableIdleTimeMillis
2675      * @see #getMinEvictableIdleTimeMillis
2676      * @see #getTimeBetweenEvictionRunsMillis
2677      * @see #setTimeBetweenEvictionRunsMillis
2678      */
2679     private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
2680 
2681     /** My hash of pools (ObjectQueue). */
2682     private Map _poolMap = null;
2683 
2684     /** The total number of active instances. */
2685     private int _totalActive = 0;
2686 
2687     /** The total number of idle instances. */
2688     private int _totalIdle = 0;
2689 
2690     /**
2691      * The number of objects subject to some form of internal processing
2692      * (usually creation or destruction) that should be included in the total
2693      * number of objects but are neither active nor idle.
2694      */
2695     private int _totalInternalProcessing = 0;
2696 
2697     /** My {@link KeyedPoolableObjectFactory}. */
2698     private KeyedPoolableObjectFactory _factory = null;
2699 
2700     /**
2701      * My idle object eviction {@link TimerTask}, if any.
2702      */
2703     private Evictor _evictor = null;
2704 
2705     /**
2706      * A cursorable list of my pools.
2707      * @see GenericKeyedObjectPool.Evictor#run
2708      */
2709     private CursorableLinkedList _poolList = null;
2710 
2711     /** Eviction cursor (over instances within-key) */
2712     private CursorableLinkedList.Cursor _evictionCursor = null;
2713     
2714     /** Eviction cursor (over keys) */
2715     private CursorableLinkedList.Cursor _evictionKeyCursor = null;
2716 
2717     /** Whether or not the pools behave as LIFO queues (last in first out) */
2718     private boolean _lifo = DEFAULT_LIFO;
2719 
2720     /**
2721      * Used to track the order in which threads call {@link #borrowObject()} so
2722      * that objects can be allocated in the order in which the threads requested
2723      * them.
2724      */
2725     private LinkedList _allocationQueue = new LinkedList();
2726 
2727 }