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