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