1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool.impl;
19
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.NoSuchElementException;
24 import java.util.Set;
25 import java.util.TreeMap;
26 import java.util.TimerTask;
27
28 import org.apache.commons.pool.BaseKeyedObjectPool;
29 import org.apache.commons.pool.KeyedObjectPool;
30 import org.apache.commons.pool.KeyedPoolableObjectFactory;
31
32 /***
33 * A configurable <code>KeyedObjectPool</code> implementation.
34 * <p>
35 * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
36 * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
37 * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map
38 * of pools, keyed on the (unique) key values provided to the
39 * {@link #preparePool preparePool}, {@link #addObject addObject} or
40 * {@link #borrowObject borrowObject} methods. Each time a new key value is
41 * provided to one of these methods, a new pool is created under the given key
42 * to be managed by the containing <code>GenericKeyedObjectPool.</code>
43 * </p>
44 * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable
45 * parameters:</p>
46 * <ul>
47 * <li>
48 * {@link #setMaxActive maxActive} controls the maximum number of objects
49 * (per key) that can be borrowed from the pool at one time. When
50 * non-positive, there is no limit to the number of objects per key.
51 * When {@link #setMaxActive maxActive} is exceeded, the keyed pool is said
52 * to be exhausted. The default setting for this parameter is 8.
53 * </li>
54 * <li>
55 * {@link #setMaxTotal maxTotal} sets a global limit on the number of objects
56 * that can be in circulation (active or idle) within the combined set of
57 * pools. When non-positive, there is no limit to the total number of
58 * objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded,
59 * all keyed pools are exhausted. When <code>maxTotal</code> is set to a
60 * positive value and {@link #borrowObject borrowObject} is invoked
61 * when at the limit with no idle instances available, an attempt is made to
62 * create room by clearing the oldest 15% of the elements from the keyed
63 * pools. The default setting for this parameter is -1 (no limit).
64 * </li>
65 * <li>
66 * {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
67 * sit idle in the pool (per key) at any time. When negative, there
68 * is no limit to the number of objects that may be idle per key. The
69 * default setting for this parameter is 8.
70 * </li>
71 * <li>
72 * {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
73 * behavior of the {@link #borrowObject borrowObject} method when a keyed
74 * pool is exhausted:
75 * <ul>
76 * <li>
77 * When {@link #setWhenExhaustedAction whenExhaustedAction} is
78 * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
79 * a {@link NoSuchElementException}
80 * </li>
81 * <li>
82 * When {@link #setWhenExhaustedAction whenExhaustedAction} is
83 * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
84 * object and return it (essentially making {@link #setMaxActive maxActive}
85 * meaningless.)
86 * </li>
87 * <li>
88 * When {@link #setWhenExhaustedAction whenExhaustedAction}
89 * is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
90 * (invoke {@link Object#wait() wait} until a new or idle object is available.
91 * If a positive {@link #setMaxWait maxWait}
92 * value is supplied, the {@link #borrowObject borrowObject} will block for at
93 * most that many milliseconds, after which a {@link NoSuchElementException}
94 * will be thrown. If {@link #setMaxWait maxWait} is non-positive,
95 * the {@link #borrowObject borrowObject} method will block indefinitely.
96 * </li>
97 * </ul>
98 * The default <code>whenExhaustedAction</code> setting is
99 * {@link #WHEN_EXHAUSTED_BLOCK}.
100 * </li>
101 * <li>
102 * When {@link #setTestOnBorrow testOnBorrow} is set, the pool will
103 * attempt to validate each object before it is returned from the
104 * {@link #borrowObject borrowObject} method. (Using the provided factory's
105 * {@link KeyedPoolableObjectFactory#validateObject validateObject} method.)
106 * Objects that fail to validate will be dropped from the pool, and a
107 * different object will be borrowed. The default setting for this parameter
108 * is <code>false.</code>
109 * </li>
110 * <li>
111 * When {@link #setTestOnReturn testOnReturn} is set, the pool will
112 * attempt to validate each object before it is returned to the pool in the
113 * {@link #returnObject returnObject} method. (Using the provided factory's
114 * {@link KeyedPoolableObjectFactory#validateObject validateObject}
115 * method.) Objects that fail to validate will be dropped from the pool.
116 * The default setting for this parameter is <code>false.</code>
117 * </li>
118 * </ul>
119 * <p>
120 * Optionally, one may configure the pool to examine and possibly evict objects
121 * as they sit idle in the pool and to ensure that a minimum number of idle
122 * objects is maintained for each key. This is performed by an
123 * "idle object eviction" thread, which runs asynchronously. Caution should be
124 * used when configuring this optional feature. Eviction runs require an
125 * exclusive synchronization lock on the pool, so if they run too frequently
126 * and / or incur excessive latency when creating, destroying or validating
127 * object instances, performance issues may result. The idle object eviction
128 * thread may be configured using the following attributes:
129 * <ul>
130 * <li>
131 * {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis}
132 * indicates how long the eviction thread should sleep before "runs" of examining
133 * idle objects. When non-positive, no eviction thread will be launched. The
134 * default setting for this parameter is -1 (i.e., by default, idle object
135 * eviction is disabled).
136 * </li>
137 * <li>
138 * {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis}
139 * specifies the minimum amount of time that an object may sit idle in the
140 * pool before it is eligible for eviction due to idle time. When
141 * non-positive, no object will be dropped from the pool due to idle time
142 * alone. This setting has no effect unless
143 * <code>timeBetweenEvictionRunsMillis > 0.</code> The default setting
144 * for this parameter is 30 minutes.
145 * </li>
146 * <li>
147 * {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle
148 * objects should be validated using the factory's
149 * {@link KeyedPoolableObjectFactory#validateObject validateObject} method
150 * during idle object eviction runs. Objects that fail to validate will be
151 * dropped from the pool. This setting has no effect unless
152 * <code>timeBetweenEvictionRunsMillis > 0.</code> The default setting
153 * for this parameter is <code>false.</code>
154 * </li>
155 * <li>
156 * {@link #setMinIdle minIdle} sets a target value for the minimum number of
157 * idle objects (per key) that should always be available. If this parameter
158 * is set to a positive number and
159 * <code>timeBetweenEvictionRunsMillis > 0,</code> each time the idle object
160 * eviction thread runs, it will try to create enough idle instances so that
161 * there will be <code>minIdle</code> idle instances available under each
162 * key. This parameter is also used by {@link #preparePool preparePool}
163 * if <code>true</code> is provided as that method's
164 * <code>populateImmediately</code> parameter. The default setting for this
165 * parameter is 0.
166 * </li>
167 * </ul>
168 * <p>
169 * The pools can be configured to behave as LIFO queues with respect to idle
170 * objects - always returning the most recently used object from the pool,
171 * or as FIFO queues, where borrowObject always returns the oldest object
172 * in the idle object pool.
173 * <ul>
174 * <li>
175 * {@link #setLifo <i>Lifo</i>}
176 * determines whether or not the pools return idle objects in
177 * last-in-first-out order. The default setting for this parameter is
178 * <code>true.</code>
179 * </li>
180 * </ul>
181 * <p>
182 * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}. A
183 * non-<code>null</code> factory must be provided either as a constructor argument
184 * or via a call to {@link #setFactory setFactory} before the pool is used.
185 * </p>
186 * @see GenericObjectPool
187 * @author Rodney Waldhoff
188 * @author Dirk Verbeeck
189 * @author Sandy McArthur
190 * @version $Revision: 609416 $ $Date: 2008-01-06 14:46:01 -0700 (Sun, 06 Jan 2008) $
191 * @since Pool 1.0
192 */
193 public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
194
195
196
197 /***
198 * A "when exhausted action" type indicating that when the pool is
199 * exhausted (i.e., the maximum number of active objects has
200 * been reached), the {@link #borrowObject}
201 * method should fail, throwing a {@link NoSuchElementException}.
202 * @see #WHEN_EXHAUSTED_BLOCK
203 * @see #WHEN_EXHAUSTED_GROW
204 * @see #setWhenExhaustedAction
205 */
206 public static final byte WHEN_EXHAUSTED_FAIL = 0;
207
208 /***
209 * A "when exhausted action" type indicating that when the pool
210 * is exhausted (i.e., the maximum number
211 * of active objects has been reached), the {@link #borrowObject}
212 * method should block until a new object is available, or the
213 * {@link #getMaxWait maximum wait time} has been reached.
214 * @see #WHEN_EXHAUSTED_FAIL
215 * @see #WHEN_EXHAUSTED_GROW
216 * @see #setMaxWait
217 * @see #getMaxWait
218 * @see #setWhenExhaustedAction
219 */
220 public static final byte WHEN_EXHAUSTED_BLOCK = 1;
221
222 /***
223 * A "when exhausted action" type indicating that when the pool is
224 * exhausted (i.e., the maximum number
225 * of active objects has been reached), the {@link #borrowObject}
226 * method should simply create a new object anyway.
227 * @see #WHEN_EXHAUSTED_FAIL
228 * @see #WHEN_EXHAUSTED_GROW
229 * @see #setWhenExhaustedAction
230 */
231 public static final byte WHEN_EXHAUSTED_GROW = 2;
232
233 /***
234 * The default cap on the number of idle instances (per key) in the pool.
235 * @see #getMaxIdle
236 * @see #setMaxIdle
237 */
238 public static final int DEFAULT_MAX_IDLE = 8;
239
240 /***
241 * The default cap on the total number of active instances (per key)
242 * from the pool.
243 * @see #getMaxActive
244 * @see #setMaxActive
245 */
246 public static final int DEFAULT_MAX_ACTIVE = 8;
247
248 /***
249 * The default cap on the the overall maximum number of objects that can
250 * exist at one time.
251 * @see #getMaxTotal
252 * @see #setMaxTotal
253 */
254 public static final int DEFAULT_MAX_TOTAL = -1;
255
256 /***
257 * The default "when exhausted action" for the pool.
258 * @see #WHEN_EXHAUSTED_BLOCK
259 * @see #WHEN_EXHAUSTED_FAIL
260 * @see #WHEN_EXHAUSTED_GROW
261 * @see #setWhenExhaustedAction
262 */
263 public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
264
265 /***
266 * The default maximum amount of time (in milliseconds) the
267 * {@link #borrowObject} method should block before throwing
268 * an exception when the pool is exhausted and the
269 * {@link #getWhenExhaustedAction "when exhausted" action} is
270 * {@link #WHEN_EXHAUSTED_BLOCK}.
271 * @see #getMaxWait
272 * @see #setMaxWait
273 */
274 public static final long DEFAULT_MAX_WAIT = -1L;
275
276 /***
277 * The default "test on borrow" value.
278 * @see #getTestOnBorrow
279 * @see #setTestOnBorrow
280 */
281 public static final boolean DEFAULT_TEST_ON_BORROW = false;
282
283 /***
284 * The default "test on return" value.
285 * @see #getTestOnReturn
286 * @see #setTestOnReturn
287 */
288 public static final boolean DEFAULT_TEST_ON_RETURN = false;
289
290 /***
291 * The default "test while idle" value.
292 * @see #getTestWhileIdle
293 * @see #setTestWhileIdle
294 * @see #getTimeBetweenEvictionRunsMillis
295 * @see #setTimeBetweenEvictionRunsMillis
296 */
297 public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
298
299 /***
300 * The default "time between eviction runs" value.
301 * @see #getTimeBetweenEvictionRunsMillis
302 * @see #setTimeBetweenEvictionRunsMillis
303 */
304 public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
305
306 /***
307 * The default number of objects to examine per run in the
308 * idle object evictor.
309 * @see #getNumTestsPerEvictionRun
310 * @see #setNumTestsPerEvictionRun
311 * @see #getTimeBetweenEvictionRunsMillis
312 * @see #setTimeBetweenEvictionRunsMillis
313 */
314 public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
315
316 /***
317 * The default value for {@link #getMinEvictableIdleTimeMillis}.
318 * @see #getMinEvictableIdleTimeMillis
319 * @see #setMinEvictableIdleTimeMillis
320 */
321 public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
322
323 /***
324 * The default minimum level of idle objects in the pool.
325 * @since Pool 1.3
326 * @see #setMinIdle
327 * @see #getMinIdle
328 */
329 public static final int DEFAULT_MIN_IDLE = 0;
330
331 /***
332 * The default LIFO status. True means that borrowObject returns the
333 * most recently used ("last in") idle object in a pool (if there are
334 * idle instances available). False means that pools behave as FIFO
335 * queues - objects are taken from idle object pools in the order that
336 * they are returned.
337 * @see #setLifo
338 */
339 public static final boolean DEFAULT_LIFO = true;
340
341
342
343 /***
344 * Create a new <code>GenericKeyedObjectPool</code> with no factory.
345 *
346 * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory)
347 * @see #setFactory(KeyedPoolableObjectFactory)
348 */
349 public GenericKeyedObjectPool() {
350 this(null,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
351 }
352
353 /***
354 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
355 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
356 */
357 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
358 this(factory,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
359 }
360
361 /***
362 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
363 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
364 * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration
365 */
366 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
367 this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.maxTotal, config.minIdle,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle,config.lifo);
368 }
369
370 /***
371 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
372 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
373 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
374 */
375 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
376 this(factory,maxActive,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
377 }
378
379 /***
380 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
381 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
382 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
383 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
384 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
385 */
386 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
387 this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
388 }
389
390 /***
391 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
392 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects 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 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
395 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
396 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
397 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
398 */
399 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) {
400 this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
401 }
402
403 /***
404 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
405 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
406 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
407 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
408 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
409 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
410 */
411 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
412 this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
413 }
414
415 /***
416 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
417 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
418 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
419 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
420 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
421 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
422 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
423 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
424 */
425 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
426 this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,testOnBorrow,testOnReturn,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
427 }
428
429 /***
430 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
431 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
432 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
433 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
434 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
435 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
436 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
437 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
438 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
439 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
440 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
441 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
442 */
443 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
444 this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
445 }
446
447 /***
448 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
449 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
450 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
451 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
452 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
453 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
454 * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
455 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
456 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
457 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
458 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
459 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
460 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
461 */
462 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
463 this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
464 }
465
466 /***
467 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
468 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
469 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
470 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
471 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
472 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
473 * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
474 * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
475 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
476 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
477 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
478 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
479 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
480 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
481 * @since Pool 1.3
482 */
483 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
484 this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, DEFAULT_LIFO);
485 }
486
487 /***
488 * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
489 * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
490 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
491 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
492 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
493 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
494 * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
495 * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
496 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
497 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
498 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
499 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
500 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
501 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
502 * @param lifo whether or not the pools behave as LIFO (last in first out) queues (see {@link #setLifo})
503 * @since Pool 1.4
504 */
505 public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, boolean lifo) {
506 _factory = factory;
507 _maxActive = maxActive;
508 _lifo = lifo;
509 switch(whenExhaustedAction) {
510 case WHEN_EXHAUSTED_BLOCK:
511 case WHEN_EXHAUSTED_FAIL:
512 case WHEN_EXHAUSTED_GROW:
513 _whenExhaustedAction = whenExhaustedAction;
514 break;
515 default:
516 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
517 }
518 _maxWait = maxWait;
519 _maxIdle = maxIdle;
520 _maxTotal = maxTotal;
521 _minIdle = minIdle;
522 _testOnBorrow = testOnBorrow;
523 _testOnReturn = testOnReturn;
524 _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
525 _numTestsPerEvictionRun = numTestsPerEvictionRun;
526 _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
527 _testWhileIdle = testWhileIdle;
528
529 _poolMap = new HashMap();
530 _poolList = new CursorableLinkedList();
531
532 startEvictor(_timeBetweenEvictionRunsMillis);
533 }
534
535
536
537
538
539 /***
540 * Returns the cap on the number of active instances per key.
541 * A negative value indicates no limit.
542 * @return the cap on the number of active instances per key.
543 * @see #setMaxActive
544 */
545 public synchronized int getMaxActive() {
546 return _maxActive;
547 }
548
549 /***
550 * Sets the cap on the number of active instances per key.
551 * @param maxActive The cap on the number of active instances per key.
552 * Use a negative value for no limit.
553 * @see #getMaxActive
554 */
555 public synchronized void setMaxActive(int maxActive) {
556 _maxActive = maxActive;
557 notifyAll();
558 }
559
560 /***
561 * Returns the overall maximum number of objects (across pools) that can
562 * exist at one time. A negative value indicates no limit.
563 * @return the maximum number of instances in circulation at one time.
564 * @see #setMaxTotal
565 */
566 public synchronized int getMaxTotal() {
567 return _maxTotal;
568 }
569
570 /***
571 * Sets the cap on the total number of instances from all pools combined.
572 * When <code>maxTotal</code> is set to a
573 * positive value and {@link #borrowObject borrowObject} is invoked
574 * when at the limit with no idle instances available, an attempt is made to
575 * create room by clearing the oldest 15% of the elements from the keyed
576 * pools.
577 *
578 * @param maxTotal The cap on the total number of instances across pools.
579 * Use a negative value for no limit.
580 * @see #getMaxTotal
581 */
582 public synchronized void setMaxTotal(int maxTotal) {
583 _maxTotal = maxTotal;
584 notifyAll();
585 }
586
587 /***
588 * Returns the action to take when the {@link #borrowObject} method
589 * is invoked when the pool is exhausted (the maximum number
590 * of "active" objects has been reached).
591 *
592 * @return one of {@link #WHEN_EXHAUSTED_BLOCK},
593 * {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
594 * @see #setWhenExhaustedAction
595 */
596 public synchronized byte getWhenExhaustedAction() {
597 return _whenExhaustedAction;
598 }
599
600 /***
601 * Sets the action to take when the {@link #borrowObject} method
602 * is invoked when the pool is exhausted (the maximum number
603 * of "active" objects has been reached).
604 *
605 * @param whenExhaustedAction the action code, which must be one of
606 * {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
607 * or {@link #WHEN_EXHAUSTED_GROW}
608 * @see #getWhenExhaustedAction
609 */
610 public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
611 switch(whenExhaustedAction) {
612 case WHEN_EXHAUSTED_BLOCK:
613 case WHEN_EXHAUSTED_FAIL:
614 case WHEN_EXHAUSTED_GROW:
615 _whenExhaustedAction = whenExhaustedAction;
616 notifyAll();
617 break;
618 default:
619 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
620 }
621 }
622
623
624 /***
625 * Returns the maximum amount of time (in milliseconds) the
626 * {@link #borrowObject} method should block before throwing
627 * an exception when the pool is exhausted and the
628 * {@link #setWhenExhaustedAction "when exhausted" action} is
629 * {@link #WHEN_EXHAUSTED_BLOCK}.
630 *
631 * When less than or equal to 0, the {@link #borrowObject} method
632 * may block indefinitely.
633 *
634 * @return the maximum number of milliseconds borrowObject will block.
635 * @see #setMaxWait
636 * @see #setWhenExhaustedAction
637 * @see #WHEN_EXHAUSTED_BLOCK
638 */
639 public synchronized long getMaxWait() {
640 return _maxWait;
641 }
642
643 /***
644 * Sets the maximum amount of time (in milliseconds) the
645 * {@link #borrowObject} method should block before throwing
646 * an exception when the pool is exhausted and the
647 * {@link #setWhenExhaustedAction "when exhausted" action} is
648 * {@link #WHEN_EXHAUSTED_BLOCK}.
649 *
650 * When less than or equal to 0, the {@link #borrowObject} method
651 * may block indefinitely.
652 *
653 * @param maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely.
654 * @see #getMaxWait
655 * @see #setWhenExhaustedAction
656 * @see #WHEN_EXHAUSTED_BLOCK
657 */
658 public synchronized void setMaxWait(long maxWait) {
659 _maxWait = maxWait;
660 }
661
662 /***
663 * Returns the cap on the number of "idle" instances per key.
664 * @return the maximum number of "idle" instances that can be held
665 * in a given keyed pool.
666 * @see #setMaxIdle
667 */
668 public synchronized int getMaxIdle() {
669 return _maxIdle;
670 }
671
672 /***
673 * Sets the cap on the number of "idle" instances in the pool.
674 * @param maxIdle the maximum number of "idle" instances that can be held
675 * in a given keyed pool. Use a negative value for no limit.
676 * @see #getMaxIdle
677 * @see #DEFAULT_MAX_IDLE
678 */
679 public synchronized void setMaxIdle(int maxIdle) {
680 _maxIdle = maxIdle;
681 notifyAll();
682 }
683
684 /***
685 * Sets the minimum number of idle objects to maintain in each of the keyed
686 * pools. This setting has no effect unless
687 * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
688 * that each pool has the required minimum number of instances are only
689 * made during idle object eviction runs.
690 * @param poolSize - The minimum size of the each keyed pool
691 * @since Pool 1.3
692 * @see #getMinIdle
693 * @see #setTimeBetweenEvictionRunsMillis
694 */
695 public synchronized void setMinIdle(int poolSize) {
696 _minIdle = poolSize;
697 }
698
699 /***
700 * Returns the minimum number of idle objects to maintain in each of the keyed
701 * pools. This setting has no effect unless
702 * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
703 * that each pool has the required minimum number of instances are only
704 * made during idle object eviction runs.
705 * @return minimum size of the each keyed pool
706 * @since Pool 1.3
707 * @see #setTimeBetweenEvictionRunsMillis
708 */
709 public synchronized int getMinIdle() {
710 return _minIdle;
711 }
712
713 /***
714 * When <code>true</code>, objects will be
715 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
716 * before being returned by the {@link #borrowObject}
717 * method. If the object fails to validate,
718 * it will be dropped from the pool, and we will attempt
719 * to borrow another.
720 *
721 * @return <code>true</code> if objects are validated before being borrowed.
722 * @see #setTestOnBorrow
723 */
724 public boolean getTestOnBorrow() {
725 return _testOnBorrow;
726 }
727
728 /***
729 * When <code>true</code>, objects will be
730 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
731 * before being returned by the {@link #borrowObject}
732 * method. If the object fails to validate,
733 * it will be dropped from the pool, and we will attempt
734 * to borrow another.
735 *
736 * @param testOnBorrow whether object should be validated before being returned by borrowObject.
737 * @see #getTestOnBorrow
738 */
739 public void setTestOnBorrow(boolean testOnBorrow) {
740 _testOnBorrow = testOnBorrow;
741 }
742
743 /***
744 * When <code>true</code>, objects will be
745 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
746 * before being returned to the pool within the
747 * {@link #returnObject}.
748 *
749 * @return <code>true</code> when objects will be validated before being returned.
750 * @see #setTestOnReturn
751 */
752 public boolean getTestOnReturn() {
753 return _testOnReturn;
754 }
755
756 /***
757 * When <code>true</code>, objects will be
758 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
759 * before being returned to the pool within the
760 * {@link #returnObject}.
761 *
762 * @param testOnReturn <code>true</code> so objects will be validated before being returned.
763 * @see #getTestOnReturn
764 */
765 public void setTestOnReturn(boolean testOnReturn) {
766 _testOnReturn = testOnReturn;
767 }
768
769 /***
770 * Returns the number of milliseconds to sleep between runs of the
771 * idle object evictor thread.
772 * When non-positive, no idle object evictor thread will be
773 * run.
774 *
775 * @return milliseconds to sleep between evictor runs.
776 * @see #setTimeBetweenEvictionRunsMillis
777 */
778 public synchronized long getTimeBetweenEvictionRunsMillis() {
779 return _timeBetweenEvictionRunsMillis;
780 }
781
782 /***
783 * Sets the number of milliseconds to sleep between runs of the
784 * idle object evictor thread.
785 * When non-positive, no idle object evictor thread will be
786 * run.
787 *
788 * @param timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs.
789 * @see #getTimeBetweenEvictionRunsMillis
790 */
791 public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
792 _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
793 startEvictor(_timeBetweenEvictionRunsMillis);
794 }
795
796 /***
797 * Returns the number of objects to examine during each run of the
798 * idle object evictor thread (if any).
799 *
800 * @return number of objects to examine each eviction run.
801 * @see #setNumTestsPerEvictionRun
802 * @see #setTimeBetweenEvictionRunsMillis
803 */
804 public synchronized int getNumTestsPerEvictionRun() {
805 return _numTestsPerEvictionRun;
806 }
807
808 /***
809 * Sets the number of objects to examine during each run of the
810 * idle object evictor thread (if any).
811 * <p>
812 * When a negative value is supplied, <code>ceil({@link #getNumIdle()})/abs({@link #getNumTestsPerEvictionRun})</code>
813 * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
814 * idle objects will be tested per run.
815 *
816 * @param numTestsPerEvictionRun number of objects to examine each eviction run.
817 * @see #getNumTestsPerEvictionRun
818 * @see #setTimeBetweenEvictionRunsMillis
819 */
820 public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
821 _numTestsPerEvictionRun = numTestsPerEvictionRun;
822 }
823
824 /***
825 * Returns the minimum amount of time an object may sit idle in the pool
826 * before it is eligible for eviction by the idle object evictor
827 * (if any).
828 *
829 * @return minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
830 * @see #setMinEvictableIdleTimeMillis
831 * @see #setTimeBetweenEvictionRunsMillis
832 */
833 public synchronized long getMinEvictableIdleTimeMillis() {
834 return _minEvictableIdleTimeMillis;
835 }
836
837 /***
838 * Sets the minimum amount of time an object may sit idle in the pool
839 * before it is eligible for eviction by the idle object evictor
840 * (if any).
841 * When non-positive, no objects will be evicted from the pool
842 * due to idle time alone.
843 *
844 * @param minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
845 * @see #getMinEvictableIdleTimeMillis
846 * @see #setTimeBetweenEvictionRunsMillis
847 */
848 public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
849 _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
850 }
851
852 /***
853 * When <code>true</code>, objects will be
854 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
855 * by the idle object evictor (if any). If an object
856 * fails to validate, it will be dropped from the pool.
857 *
858 * @return <code>true</code> when objects are validated when borrowed.
859 * @see #setTestWhileIdle
860 * @see #setTimeBetweenEvictionRunsMillis
861 */
862 public synchronized boolean getTestWhileIdle() {
863 return _testWhileIdle;
864 }
865
866 /***
867 * When <code>true</code>, objects will be
868 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
869 * by the idle object evictor (if any). If an object
870 * fails to validate, it will be dropped from the pool.
871 *
872 * @param testWhileIdle <code>true</code> so objects are validated when borrowed.
873 * @see #getTestWhileIdle
874 * @see #setTimeBetweenEvictionRunsMillis
875 */
876 public synchronized void setTestWhileIdle(boolean testWhileIdle) {
877 _testWhileIdle = testWhileIdle;
878 }
879
880 /***
881 * Sets the configuration.
882 * @param conf the new configuration to use.
883 * @see GenericKeyedObjectPool.Config
884 */
885 public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
886 setMaxIdle(conf.maxIdle);
887 setMaxActive(conf.maxActive);
888 setMaxTotal(conf.maxTotal);
889 setMinIdle(conf.minIdle);
890 setMaxWait(conf.maxWait);
891 setWhenExhaustedAction(conf.whenExhaustedAction);
892 setTestOnBorrow(conf.testOnBorrow);
893 setTestOnReturn(conf.testOnReturn);
894 setTestWhileIdle(conf.testWhileIdle);
895 setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
896 setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
897 setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
898 }
899
900 /***
901 * Whether or not the idle object pools act as LIFO queues. True means
902 * that borrowObject returns the most recently used ("last in") idle object
903 * in a pool (if there are idle instances available). False means that
904 * the pools behave as FIFO queues - objects are taken from idle object
905 * pools in the order that they are returned.
906 *
907 * @return <code>true</code> if the pools are configured to act as LIFO queues
908 * @since 1.4
909 */
910 public synchronized boolean getLifo() {
911 return _lifo;
912 }
913
914 /***
915 * Sets the LIFO property of the pools. True means that borrowObject returns
916 * the most recently used ("last in") idle object in a pool (if there are
917 * idle instances available). False means that the pools behave as FIFO
918 * queues - objects are taken from idle object pools in the order that
919 * they are returned.
920 *
921 * @param lifo the new value for the lifo property
922 * @since 1.4
923 */
924 public synchronized void setLifo(boolean lifo) {
925 this._lifo = lifo;
926 }
927
928
929
930 public Object borrowObject(Object key) throws Exception {
931 long starttime = System.currentTimeMillis();
932 boolean newlyCreated = false;
933 for(;;) {
934 ObjectTimestampPair pair = null;
935 ObjectQueue pool = null;
936 synchronized (this) {
937 assertOpen();
938 pool = (ObjectQueue)(_poolMap.get(key));
939 if(null == pool) {
940 pool = new ObjectQueue();
941 _poolMap.put(key,pool);
942 _poolList.add(key);
943 }
944
945 try {
946 pair = (ObjectTimestampPair)(pool.queue.removeFirst());
947 if(null != pair) {
948 _totalIdle--;
949 }
950 } catch(NoSuchElementException e) {
951 }
952
953 if(null == pair) {
954
955
956 if ((_maxTotal > 0) && (_totalActive + _totalIdle >= _maxTotal)) {
957 clearOldest();
958 }
959
960
961
962 if ((_maxActive < 0 || pool.activeCount < _maxActive) &&
963 (_maxTotal < 0 || _totalActive + _totalIdle < _maxTotal)) {
964 Object obj = _factory.makeObject(key);
965 pair = new ObjectTimestampPair(obj);
966 newlyCreated = true;
967 } else {
968
969 switch(_whenExhaustedAction) {
970 case WHEN_EXHAUSTED_GROW:
971 Object obj = _factory.makeObject(key);
972 pair = new ObjectTimestampPair(obj);
973 break;
974 case WHEN_EXHAUSTED_FAIL:
975 throw new NoSuchElementException();
976 case WHEN_EXHAUSTED_BLOCK:
977 try {
978 if(_maxWait <= 0) {
979 wait();
980 } else {
981
982
983 final long elapsed = (System.currentTimeMillis() - starttime);
984 final long waitTime = _maxWait - elapsed;
985 if (waitTime > 0)
986 {
987 wait(waitTime);
988 }
989 }
990 } catch(InterruptedException e) {
991
992 }
993 if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
994 throw new NoSuchElementException("Timeout waiting for idle object");
995 } else {
996 continue;
997 }
998 default:
999 throw new IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " not recognized.");
1000 }
1001 }
1002 }
1003 pool.incrementActiveCount();
1004 }
1005
1006
1007
1008
1009 try {
1010 _factory.activateObject(key, pair.value);
1011 } catch (Exception e) {
1012 try {
1013 _factory.destroyObject(key,pair.value);
1014 synchronized (this) {
1015 pool.decrementActiveCount();
1016 }
1017 } catch (Exception e2) {
1018
1019 }
1020 if(newlyCreated) {
1021 throw new NoSuchElementException(
1022 "Could not create a validated object, cause: "
1023 + e.getMessage());
1024 }
1025 else {
1026 continue;
1027 }
1028 }
1029
1030
1031
1032
1033 boolean invalid = true;
1034 try {
1035 invalid = _testOnBorrow && !_factory.validateObject(key, pair.value);
1036 } catch (Exception e) {
1037
1038 }
1039 if (invalid) {
1040 try {
1041 _factory.destroyObject(key,pair.value);
1042 synchronized (this) {
1043 pool.decrementActiveCount();
1044 }
1045 } catch (Exception e) {
1046
1047 }
1048 if(newlyCreated) {
1049 throw new NoSuchElementException("Could not create a validated object");
1050 }
1051 } else {
1052 return pair.value;
1053 }
1054 }
1055 }
1056
1057 /***
1058 * Clears the pool, removing all pooled instances.
1059 */
1060 public synchronized void clear() {
1061 for(Iterator entries = _poolMap.entrySet().iterator(); entries.hasNext(); ) {
1062 final Map.Entry entry = (Map.Entry)entries.next();
1063 final Object key = entry.getKey();
1064 final CursorableLinkedList list = ((ObjectQueue)(entry.getValue())).queue;
1065 for(Iterator it = list.iterator(); it.hasNext(); ) {
1066 try {
1067 _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
1068 } catch(Exception e) {
1069
1070 }
1071 it.remove();
1072 }
1073 }
1074 _poolMap.clear();
1075 _poolList.clear();
1076 _totalIdle = 0;
1077 notifyAll();
1078 }
1079
1080 /***
1081 * Method clears oldest 15% of objects in pool. The method sorts the
1082 * objects into a TreeMap and then iterates the first 15% for removal
1083 * @since Pool 1.3
1084 */
1085 public synchronized void clearOldest() {
1086
1087 final Map map = new TreeMap();
1088 for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
1089 final Object key = keyiter.next();
1090 final CursorableLinkedList list = ((ObjectQueue)_poolMap.get(key)).queue;
1091 for (Iterator it = list.iterator(); it.hasNext();) {
1092
1093
1094
1095 map.put(it.next(), key);
1096 }
1097 }
1098
1099
1100 Set setPairKeys = map.entrySet();
1101 int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
1102
1103 Iterator iter = setPairKeys.iterator();
1104 while (iter.hasNext() && itemsToRemove > 0) {
1105 Map.Entry entry = (Map.Entry) iter.next();
1106
1107
1108
1109 Object key = entry.getValue();
1110 ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
1111 final CursorableLinkedList list =
1112 ((ObjectQueue)(_poolMap.get(key))).queue;
1113 list.remove(pairTimeStamp);
1114
1115 try {
1116 _factory.destroyObject(key, pairTimeStamp.value);
1117 } catch (Exception e) {
1118
1119 }
1120
1121 if (list.isEmpty()) {
1122 _poolMap.remove(key);
1123 _poolList.remove(key);
1124 }
1125 _totalIdle--;
1126 itemsToRemove--;
1127 }
1128 notifyAll();
1129 }
1130
1131 /***
1132 * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
1133 *
1134 * @param key the key to clear
1135 */
1136 public synchronized void clear(Object key) {
1137 final ObjectQueue pool = (ObjectQueue)(_poolMap.remove(key));
1138 if(null == pool) {
1139 return;
1140 } else {
1141 _poolList.remove(key);
1142 for(Iterator it = pool.queue.iterator(); it.hasNext(); ) {
1143 try {
1144 _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
1145 } catch(Exception e) {
1146
1147 }
1148 it.remove();
1149 _totalIdle--;
1150 }
1151 }
1152
1153 notifyAll();
1154 }
1155
1156 /***
1157 * Returns the total number of instances current borrowed from this pool but not yet returned.
1158 *
1159 * @return the total number of instances currently borrowed from this pool
1160 */
1161 public synchronized int getNumActive() {
1162 return _totalActive;
1163 }
1164
1165 /***
1166 * Returns the total number of instances currently idle in this pool.
1167 *
1168 * @return the total number of instances currently idle in this pool
1169 */
1170 public synchronized int getNumIdle() {
1171 return _totalIdle;
1172 }
1173
1174 /***
1175 * Returns the number of instances currently borrowed from but not yet returned
1176 * to the pool corresponding to the given <code>key</code>.
1177 *
1178 * @param key the key to query
1179 * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
1180 */
1181 public synchronized int getNumActive(Object key) {
1182 final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1183 return pool != null ? pool.activeCount : 0;
1184 }
1185
1186 /***
1187 * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
1188 *
1189 * @param key the key to query
1190 * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
1191 */
1192 public synchronized int getNumIdle(Object key) {
1193 final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1194 return pool != null ? pool.queue.size() : 0;
1195 }
1196
1197 public void returnObject(Object key, Object obj) throws Exception {
1198 try {
1199 addObjectToPool(key, obj, true);
1200 } catch (Exception e) {
1201 if (_factory != null) {
1202 try {
1203 _factory.destroyObject(key, obj);
1204 } catch (Exception e2) {
1205
1206 }
1207
1208
1209
1210 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1211 if (pool != null) {
1212 synchronized(this) {
1213 pool.decrementActiveCount();
1214 notifyAll();
1215 }
1216 }
1217 }
1218 }
1219 }
1220
1221 private void addObjectToPool(Object key, Object obj,
1222 boolean decrementNumActive) throws Exception {
1223
1224
1225 boolean success = true;
1226 if(_testOnReturn && !_factory.validateObject(key, obj)) {
1227 success = false;
1228 } else {
1229 _factory.passivateObject(key, obj);
1230 }
1231
1232 boolean shouldDestroy = !success;
1233 ObjectQueue pool;
1234
1235
1236
1237 synchronized (this) {
1238
1239 pool = (ObjectQueue) (_poolMap.get(key));
1240
1241 if(null == pool) {
1242 pool = new ObjectQueue();
1243 _poolMap.put(key, pool);
1244 _poolList.add(key);
1245 }
1246 if (isClosed()) {
1247 shouldDestroy = true;
1248 } else {
1249
1250
1251 if(_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) {
1252 shouldDestroy = true;
1253 } else if(success) {
1254
1255
1256 if (_lifo) {
1257 pool.queue.addFirst(new ObjectTimestampPair(obj));
1258 } else {
1259 pool.queue.addLast(new ObjectTimestampPair(obj));
1260 }
1261 _totalIdle++;
1262 }
1263 }
1264 }
1265
1266
1267 if(shouldDestroy) {
1268 try {
1269 _factory.destroyObject(key, obj);
1270 } catch(Exception e) {
1271
1272 }
1273 }
1274
1275
1276 if (decrementNumActive) {
1277 synchronized(this) {
1278 pool.decrementActiveCount();
1279 notifyAll();
1280 }
1281 }
1282 }
1283
1284 public void invalidateObject(Object key, Object obj) throws Exception {
1285 try {
1286 _factory.destroyObject(key, obj);
1287 } finally {
1288 synchronized (this) {
1289 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1290 if(null == pool) {
1291 pool = new ObjectQueue();
1292 _poolMap.put(key, pool);
1293 _poolList.add(key);
1294 }
1295 pool.decrementActiveCount();
1296 notifyAll();
1297 }
1298 }
1299 }
1300
1301 /***
1302 * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
1303 * passivate it, and then place it in the idle object pool.
1304 * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
1305 *
1306 * @param key the key a new instance should be added to
1307 * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
1308 * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been called on this pool.
1309 */
1310 public void addObject(Object key) throws Exception {
1311 assertOpen();
1312 if (_factory == null) {
1313 throw new IllegalStateException("Cannot add objects without a factory.");
1314 }
1315 Object obj = _factory.makeObject(key);
1316 synchronized (this) {
1317 try {
1318 assertOpen();
1319 addObjectToPool(key, obj, false);
1320 } catch (IllegalStateException ex) {
1321 try {
1322 _factory.destroyObject(key, obj);
1323 } catch (Exception ex2) {
1324
1325 }
1326 throw ex;
1327 }
1328 }
1329 }
1330
1331 /***
1332 * Registers a key for pool control.
1333 *
1334 * If <code>populateImmediately</code> is <code>true</code> and
1335 * <code>minIdle > 0,</code> the pool under the given key will be
1336 * populated immediately with <code>minIdle</code> idle instances.
1337 *
1338 * @param key - The key to register for pool control.
1339 * @param populateImmediately - If this is <code>true</code>, the pool
1340 * will be populated immediately.
1341 * @since Pool 1.3
1342 */
1343 public synchronized void preparePool(Object key, boolean populateImmediately) {
1344 ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1345 if (null == pool) {
1346 pool = new ObjectQueue();
1347 _poolMap.put(key,pool);
1348 _poolList.add(key);
1349 }
1350
1351 if (populateImmediately) {
1352 try {
1353
1354 ensureMinIdle(key);
1355 }
1356 catch (Exception e) {
1357
1358 }
1359 }
1360 }
1361
1362 public void close() throws Exception {
1363 super.close();
1364 synchronized (this) {
1365 clear();
1366 if(null != _evictionCursor) {
1367 _evictionCursor.close();
1368 _evictionCursor = null;
1369 }
1370 if(null != _evictionKeyCursor) {
1371 _evictionKeyCursor.close();
1372 _evictionKeyCursor = null;
1373 }
1374 startEvictor(-1L);
1375 }
1376 }
1377
1378 public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
1379 assertOpen();
1380 if(0 < getNumActive()) {
1381 throw new IllegalStateException("Objects are already active");
1382 } else {
1383 clear();
1384 _factory = factory;
1385 }
1386 }
1387
1388 /***
1389 * <p>Perform <code>numTests</code> idle object eviction tests, evicting
1390 * examined objects that meet the criteria for eviction. If
1391 * <code>testWhileIdle</code> is true, examined objects are validated
1392 * when visited (and removed if invalid); otherwise only objects that
1393 * have been idle for more than <code>minEvicableIdletimeMillis</code>
1394 * are removed.</p>
1395 *
1396 * <p>Successive activations of this method examine objects in keyed pools
1397 * in sequence, cycling through the keys and examining objects in
1398 * oldest-to-youngest order within the keyed pools.</p>
1399 *
1400 * @throws Exception when there is a problem evicting idle objects.
1401 */
1402 public synchronized void evict() throws Exception {
1403
1404 Object key = null;
1405 if (_evictionKeyCursor != null &&
1406 _evictionKeyCursor._lastReturned != null) {
1407 key = _evictionKeyCursor._lastReturned.value();
1408 }
1409
1410 for (int i=0,m=getNumTests(); i<m; i++) {
1411
1412 if (_poolMap == null || _poolMap.size() == 0) {
1413 continue;
1414 }
1415
1416
1417 if (null == _evictionKeyCursor) {
1418 resetEvictionKeyCursor();
1419 key = null;
1420 }
1421
1422
1423 if (null == _evictionCursor) {
1424
1425 if (_evictionKeyCursor.hasNext()) {
1426 key = _evictionKeyCursor.next();
1427 resetEvictionObjectCursor(key);
1428 } else {
1429
1430 resetEvictionKeyCursor();
1431 if (_evictionKeyCursor != null) {
1432 if (_evictionKeyCursor.hasNext()) {
1433 key = _evictionKeyCursor.next();
1434 resetEvictionObjectCursor(key);
1435 }
1436 }
1437 }
1438 }
1439
1440 if (_evictionCursor == null) {
1441 continue;
1442 }
1443
1444
1445
1446 if((_lifo && !_evictionCursor.hasPrevious()) ||
1447 (!_lifo && !_evictionCursor.hasNext())) {
1448 if (_evictionKeyCursor != null) {
1449 if (_evictionKeyCursor.hasNext()) {
1450 key = _evictionKeyCursor.next();
1451 resetEvictionObjectCursor(key);
1452 } else {
1453 resetEvictionKeyCursor();
1454 if (_evictionKeyCursor != null) {
1455 if (_evictionKeyCursor.hasNext()) {
1456 key = _evictionKeyCursor.next();
1457 resetEvictionObjectCursor(key);
1458 }
1459 }
1460 }
1461 }
1462 }
1463
1464 if((_lifo && !_evictionCursor.hasPrevious()) ||
1465 (!_lifo && !_evictionCursor.hasNext())) {
1466 continue;
1467 }
1468
1469
1470
1471 ObjectTimestampPair pair = _lifo ?
1472 (ObjectTimestampPair) _evictionCursor.previous() :
1473 (ObjectTimestampPair) _evictionCursor.next();
1474 boolean removeObject=false;
1475 if((_minEvictableIdleTimeMillis > 0) &&
1476 (System.currentTimeMillis() - pair.tstamp >
1477 _minEvictableIdleTimeMillis)) {
1478 removeObject=true;
1479 }
1480 if(_testWhileIdle && removeObject == false) {
1481 boolean active = false;
1482 try {
1483 _factory.activateObject(key,pair.value);
1484 active = true;
1485 } catch(Exception e) {
1486 removeObject=true;
1487 }
1488 if(active) {
1489 if(!_factory.validateObject(key,pair.value)) {
1490 removeObject=true;
1491 } else {
1492 try {
1493 _factory.passivateObject(key,pair.value);
1494 } catch(Exception e) {
1495 removeObject=true;
1496 }
1497 }
1498 }
1499 }
1500 if(removeObject) {
1501 try {
1502 _evictionCursor.remove();
1503 _totalIdle--;
1504 _factory.destroyObject(key, pair.value);
1505
1506
1507
1508
1509
1510
1511 if (_minIdle == 0) {
1512 ObjectQueue objectQueue =
1513 (ObjectQueue)_poolMap.get(key);
1514 if (objectQueue != null &&
1515 objectQueue.queue.isEmpty()) {
1516 _poolMap.remove(key);
1517 _poolList.remove(key);
1518 }
1519 }
1520 } catch(Exception e) {
1521 ;
1522 }
1523 }
1524 }
1525 }
1526
1527 /***
1528 * Resets the eviction key cursor and closes any
1529 * associated eviction object cursor
1530 */
1531 private void resetEvictionKeyCursor() {
1532 if (_evictionKeyCursor != null) {
1533 _evictionKeyCursor.close();
1534 }
1535 _evictionKeyCursor = _poolList.cursor();
1536 if (null != _evictionCursor) {
1537 _evictionCursor.close();
1538 _evictionCursor = null;
1539 }
1540 }
1541
1542 /***
1543 * Resets the eviction object cursor for the given key
1544 *
1545 * @param key eviction key
1546 */
1547 private void resetEvictionObjectCursor(Object key) {
1548 if (_evictionCursor != null) {
1549 _evictionCursor.close();
1550 }
1551 if (_poolMap == null) {
1552 return;
1553 }
1554 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1555 if (pool != null) {
1556 CursorableLinkedList queue =
1557 (CursorableLinkedList)(pool.queue);
1558 _evictionCursor = queue.cursor(_lifo ? queue.size() : 0);
1559 }
1560 }
1561
1562 /***
1563 * Iterates through all the known keys and creates any necessary objects to maintain
1564 * the minimum level of pooled objects.
1565 * @see #getMinIdle
1566 * @see #setMinIdle
1567 * @throws Exception If there was an error whilst creating the pooled objects.
1568 */
1569 private synchronized void ensureMinIdle() throws Exception {
1570 Iterator iterator = _poolMap.keySet().iterator();
1571
1572
1573 if (_minIdle > 0) {
1574
1575
1576
1577
1578 while (iterator.hasNext()) {
1579
1580 Object key = iterator.next();
1581 ensureMinIdle(key);
1582 }
1583 }
1584 }
1585
1586 /***
1587 * Re-creates any needed objects to maintain the minimum levels of
1588 * pooled objects for the specified key.
1589 *
1590 * This method uses {@link #calculateDefecit} to calculate the number
1591 * of objects to be created. {@link #calculateDefecit} can be overridden to
1592 * provide a different method of calculating the number of objects to be
1593 * created.
1594 * @param key The key to process
1595 * @throws Exception If there was an error whilst creating the pooled objects
1596 */
1597 private synchronized void ensureMinIdle(Object key) throws Exception {
1598
1599 int numberToCreate = calculateDefecit(key);
1600
1601
1602 for (int i = 0; i < numberToCreate; i++) {
1603 addObject(key);
1604 }
1605 }
1606
1607
1608
1609 /***
1610 * Start the eviction thread or service, or when
1611 * <code>delay</code> is non-positive, stop it
1612 * if it is already running.
1613 *
1614 * @param delay milliseconds between evictor runs.
1615 */
1616 protected synchronized void startEvictor(long delay) {
1617 if(null != _evictor) {
1618 EvictionTimer.cancel(_evictor);
1619 _evictor = null;
1620 }
1621 if(delay > 0) {
1622 _evictor = new Evictor();
1623 EvictionTimer.schedule(_evictor, delay, delay);
1624 }
1625 }
1626
1627 synchronized String debugInfo() {
1628 StringBuffer buf = new StringBuffer();
1629 buf.append("Active: ").append(getNumActive()).append("\n");
1630 buf.append("Idle: ").append(getNumIdle()).append("\n");
1631 Iterator it = _poolMap.keySet().iterator();
1632 while(it.hasNext()) {
1633 buf.append("\t").append(_poolMap.get(it.next())).append("\n");
1634 }
1635 return buf.toString();
1636 }
1637
1638 private int getNumTests() {
1639 if(_numTestsPerEvictionRun >= 0) {
1640 return _numTestsPerEvictionRun;
1641 } else {
1642 return(int)(Math.ceil((double)_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
1643 }
1644 }
1645
1646 /***
1647 * This returns the number of objects to create during the pool
1648 * sustain cycle. This will ensure that the minimum number of idle
1649 * connections is maintained without going past the maxPool value.
1650 * <p>
1651 * This method has been left public so derived classes can override
1652 * the way the defecit is calculated. ie... Increase/decrease the pool
1653 * size at certain times of day to accomodate for usage patterns.
1654 *
1655 * @param key - The key of the pool to calculate the number of
1656 * objects to be re-created
1657 * @return The number of objects to be created
1658 */
1659 private int calculateDefecit(Object key) {
1660 int objectDefecit = 0;
1661
1662
1663
1664 objectDefecit = getMinIdle() - getNumIdle(key);
1665 if (getMaxActive() > 0) {
1666 int growLimit = Math.max(0, getMaxActive() - getNumActive(key) - getNumIdle(key));
1667 objectDefecit = Math.min(objectDefecit, growLimit);
1668 }
1669
1670
1671 if (getMaxTotal() > 0) {
1672 int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle());
1673 objectDefecit = Math.min(objectDefecit, growLimit);
1674 }
1675
1676 return objectDefecit;
1677 }
1678
1679
1680
1681 /***
1682 * A "struct" that keeps additional information about the actual queue of pooled objects.
1683 */
1684 private class ObjectQueue {
1685 private int activeCount = 0;
1686 private final CursorableLinkedList queue = new CursorableLinkedList();
1687
1688 void incrementActiveCount() {
1689 _totalActive++;
1690 activeCount++;
1691 }
1692
1693 void decrementActiveCount() {
1694 _totalActive--;
1695 if (activeCount > 0) {
1696 activeCount--;
1697 }
1698 }
1699 }
1700
1701 /***
1702 * A simple "struct" encapsulating an object instance and a timestamp.
1703 *
1704 * Implements Comparable, objects are sorted from old to new.
1705 *
1706 * This is also used by {@link GenericObjectPool}.
1707 */
1708 static class ObjectTimestampPair implements Comparable {
1709 Object value;
1710 long tstamp;
1711
1712 ObjectTimestampPair(Object val) {
1713 this(val, System.currentTimeMillis());
1714 }
1715
1716 ObjectTimestampPair(Object val, long time) {
1717 value = val;
1718 tstamp = time;
1719 }
1720
1721 public String toString() {
1722 return value + ";" + tstamp;
1723 }
1724
1725 public int compareTo(Object obj) {
1726 return compareTo((ObjectTimestampPair) obj);
1727 }
1728
1729 public int compareTo(ObjectTimestampPair other) {
1730 final long tstampdiff = this.tstamp - other.tstamp;
1731 if (tstampdiff == 0) {
1732
1733
1734 return System.identityHashCode(this) - System.identityHashCode(other);
1735 } else {
1736
1737 return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
1738 }
1739 }
1740 }
1741
1742 /***
1743 * The idle object evictor {@link TimerTask}.
1744 * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
1745 */
1746 private class Evictor extends TimerTask {
1747 public void run() {
1748
1749 try {
1750 evict();
1751 } catch(Exception e) {
1752
1753 }
1754
1755 try {
1756 ensureMinIdle();
1757 } catch (Exception e) {
1758
1759 }
1760 }
1761 }
1762
1763 /***
1764 * A simple "struct" encapsulating the
1765 * configuration information for a <code>GenericKeyedObjectPool</code>.
1766 * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
1767 * @see GenericKeyedObjectPool#setConfig
1768 */
1769 public static class Config {
1770 /***
1771 * @see GenericKeyedObjectPool#setMaxIdle
1772 */
1773 public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
1774 /***
1775 * @see GenericKeyedObjectPool#setMaxActive
1776 */
1777 public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
1778 /***
1779 * @see GenericKeyedObjectPool#setMaxTotal
1780 */
1781 public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
1782 /***
1783 * @see GenericKeyedObjectPool#setMinIdle
1784 */
1785 public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
1786 /***
1787 * @see GenericKeyedObjectPool#setMaxWait
1788 */
1789 public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
1790 /***
1791 * @see GenericKeyedObjectPool#setWhenExhaustedAction
1792 */
1793 public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
1794 /***
1795 * @see GenericKeyedObjectPool#setTestOnBorrow
1796 */
1797 public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
1798 /***
1799 * @see GenericKeyedObjectPool#setTestOnReturn
1800 */
1801 public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
1802 /***
1803 * @see GenericKeyedObjectPool#setTestWhileIdle
1804 */
1805 public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
1806 /***
1807 * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
1808 */
1809 public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1810 /***
1811 * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun
1812 */
1813 public int numTestsPerEvictionRun = GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1814 /***
1815 * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis
1816 */
1817 public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1818 /***
1819 * @see GenericKeyedObjectPool#setLifo
1820 */
1821 public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO;
1822 }
1823
1824
1825
1826 /***
1827 * The cap on the number of idle instances in the pool.
1828 * @see #setMaxIdle
1829 * @see #getMaxIdle
1830 */
1831 private int _maxIdle = DEFAULT_MAX_IDLE;
1832
1833 /***
1834 * The minimum no of idle objects to keep in the pool.
1835 * @see #setMinIdle
1836 * @see #getMinIdle
1837 */
1838 private int _minIdle = DEFAULT_MIN_IDLE;
1839
1840 /***
1841 * The cap on the number of active instances from the pool.
1842 * @see #setMaxActive
1843 * @see #getMaxActive
1844 */
1845 private int _maxActive = DEFAULT_MAX_ACTIVE;
1846
1847 /***
1848 * The cap on the total number of instances from the pool if non-positive.
1849 * @see #setMaxTotal
1850 * @see #getMaxTotal
1851 */
1852 private int _maxTotal = DEFAULT_MAX_TOTAL;
1853
1854 /***
1855 * The maximum amount of time (in millis) the
1856 * {@link #borrowObject} method should block before throwing
1857 * an exception when the pool is exhausted and the
1858 * {@link #getWhenExhaustedAction "when exhausted" action} is
1859 * {@link #WHEN_EXHAUSTED_BLOCK}.
1860 *
1861 * When less than or equal to 0, the {@link #borrowObject} method
1862 * may block indefinitely.
1863 *
1864 * @see #setMaxWait
1865 * @see #getMaxWait
1866 * @see #WHEN_EXHAUSTED_BLOCK
1867 * @see #setWhenExhaustedAction
1868 * @see #getWhenExhaustedAction
1869 */
1870 private long _maxWait = DEFAULT_MAX_WAIT;
1871
1872 /***
1873 * The action to take when the {@link #borrowObject} method
1874 * is invoked when the pool is exhausted (the maximum number
1875 * of "active" objects has been reached).
1876 *
1877 * @see #WHEN_EXHAUSTED_BLOCK
1878 * @see #WHEN_EXHAUSTED_FAIL
1879 * @see #WHEN_EXHAUSTED_GROW
1880 * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
1881 * @see #setWhenExhaustedAction
1882 * @see #getWhenExhaustedAction
1883 */
1884 private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
1885
1886 /***
1887 * When <code>true</code>, objects will be
1888 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1889 * before being returned by the {@link #borrowObject}
1890 * method. If the object fails to validate,
1891 * it will be dropped from the pool, and we will attempt
1892 * to borrow another.
1893 *
1894 * @see #setTestOnBorrow
1895 * @see #getTestOnBorrow
1896 */
1897 private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
1898
1899 /***
1900 * When <code>true</code>, objects will be
1901 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1902 * before being returned to the pool within the
1903 * {@link #returnObject}.
1904 *
1905 * @see #getTestOnReturn
1906 * @see #setTestOnReturn
1907 */
1908 private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
1909
1910 /***
1911 * When <code>true</code>, objects will be
1912 * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1913 * by the idle object evictor (if any). If an object
1914 * fails to validate, it will be dropped from the pool.
1915 *
1916 * @see #setTestWhileIdle
1917 * @see #getTestWhileIdle
1918 * @see #getTimeBetweenEvictionRunsMillis
1919 * @see #setTimeBetweenEvictionRunsMillis
1920 */
1921 private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
1922
1923 /***
1924 * The number of milliseconds to sleep between runs of the
1925 * idle object evictor thread.
1926 * When non-positive, no idle object evictor thread will be
1927 * run.
1928 *
1929 * @see #setTimeBetweenEvictionRunsMillis
1930 * @see #getTimeBetweenEvictionRunsMillis
1931 */
1932 private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1933
1934 /***
1935 * The number of objects to examine during each run of the
1936 * idle object evictor thread (if any).
1937 * <p>
1938 * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
1939 * tests will be run. I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
1940 * idle objects will be tested per run.
1941 *
1942 * @see #setNumTestsPerEvictionRun
1943 * @see #getNumTestsPerEvictionRun
1944 * @see #getTimeBetweenEvictionRunsMillis
1945 * @see #setTimeBetweenEvictionRunsMillis
1946 */
1947 private int _numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1948
1949 /***
1950 * The minimum amount of time an object may sit idle in the pool
1951 * before it is eligible for eviction by the idle object evictor
1952 * (if any).
1953 * When non-positive, no objects will be evicted from the pool
1954 * due to idle time alone.
1955 *
1956 * @see #setMinEvictableIdleTimeMillis
1957 * @see #getMinEvictableIdleTimeMillis
1958 * @see #getTimeBetweenEvictionRunsMillis
1959 * @see #setTimeBetweenEvictionRunsMillis
1960 */
1961 private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1962
1963 /*** My hash of pools (ObjectQueue). */
1964 private Map _poolMap = null;
1965
1966 /*** The total number of active instances. */
1967 private int _totalActive = 0;
1968
1969 /*** The total number of idle instances. */
1970 private int _totalIdle = 0;
1971
1972 /*** My {@link KeyedPoolableObjectFactory}. */
1973 private KeyedPoolableObjectFactory _factory = null;
1974
1975 /***
1976 * My idle object eviction {@link TimerTask}, if any.
1977 */
1978 private Evictor _evictor = null;
1979
1980 /***
1981 * A cursorable list of my pools.
1982 * @see GenericKeyedObjectPool.Evictor#run
1983 */
1984 private CursorableLinkedList _poolList = null;
1985
1986 private CursorableLinkedList.Cursor _evictionCursor = null;
1987 private CursorableLinkedList.Cursor _evictionKeyCursor = null;
1988
1989 /*** Whether or not the pools behave as LIFO queues (last in first out) */
1990 private boolean _lifo = DEFAULT_LIFO;
1991 }