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