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