1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool.impl;
18
19 import java.util.Iterator;
20 import java.util.NoSuchElementException;
21 import java.util.LinkedList;
22 import java.util.ListIterator;
23 import java.util.Timer;
24 import java.util.TimerTask;
25
26 import org.apache.commons.pool.BaseObjectPool;
27 import org.apache.commons.pool.ObjectPool;
28 import org.apache.commons.pool.PoolableObjectFactory;
29 import org.apache.commons.pool.impl.GenericKeyedObjectPool.ObjectTimestampPair;
30
31 /***
32 * A configurable {@link ObjectPool} implementation.
33 * <p>
34 * When coupled with the appropriate {@link PoolableObjectFactory},
35 * <tt>GenericObjectPool</tt> provides robust pooling functionality for
36 * arbitrary objects.
37 * <p>
38 * A <tt>GenericObjectPool</tt> provides a number of configurable parameters:
39 * <ul>
40 * <li>
41 * {@link #setMaxActive <i>maxActive</i>} controls the maximum number of objects that can
42 * be borrowed from the pool at one time. When non-positive, there
43 * is no limit to the number of objects that may be active at one time.
44 * When {@link #setMaxActive <i>maxActive</i>} is exceeded, the pool is said to be exhausted.
45 * </li>
46 * <li>
47 * {@link #setMaxIdle <i>maxIdle</i>} controls the maximum number of objects that can
48 * sit idle in the pool at any time. When negative, there
49 * is no limit to the number of objects that may be idle at one time.
50 * </li>
51 * <li>
52 * {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} specifies the
53 * behaviour of the {@link #borrowObject} method when the pool is exhausted:
54 * <ul>
55 * <li>
56 * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
57 * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject} will throw
58 * a {@link NoSuchElementException}
59 * </li>
60 * <li>
61 * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
62 * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject} will create a new
63 * object and return it(essentially making {@link #setMaxActive <i>maxActive</i>}
64 * meaningless.)
65 * </li>
66 * <li>
67 * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>}
68 * is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject} will block
69 * (invoke {@link Object#wait} until a new or idle object is available.
70 * If a positive {@link #setMaxWait <i>maxWait</i>}
71 * value is supplied, the {@link #borrowObject} will block for at
72 * most that many milliseconds, after which a {@link NoSuchElementException}
73 * will be thrown. If {@link #setMaxWait <i>maxWait</i>} is non-positive,
74 * the {@link #borrowObject} method will block indefinitely.
75 * </li>
76 * </ul>
77 * </li>
78 * <li>
79 * When {@link #setTestOnBorrow <i>testOnBorrow</i>} is set, the pool will
80 * attempt to validate each object before it is returned from the
81 * {@link #borrowObject} method. (Using the provided factory's
82 * {@link PoolableObjectFactory#validateObject} method.) Objects that fail
83 * to validate will be dropped from the pool, and a different object will
84 * be borrowed.
85 * </li>
86 * <li>
87 * When {@link #setTestOnReturn <i>testOnReturn</i>} is set, the pool will
88 * attempt to validate each object before it is returned to the pool in the
89 * {@link #returnObject} method. (Using the provided factory's
90 * {@link PoolableObjectFactory#validateObject}
91 * method.) Objects that fail to validate will be dropped from the pool.
92 * </li>
93 * </ul>
94 * <p>
95 * Optionally, one may configure the pool to examine and possibly evict objects as they
96 * sit idle in the pool. This is performed by an "idle object eviction" thread, which
97 * runs asychronously. The idle object eviction thread may be configured using the
98 * following attributes:
99 * <ul>
100 * <li>
101 * {@link #setTimeBetweenEvictionRunsMillis <i>timeBetweenEvictionRunsMillis</i>}
102 * indicates how long the eviction thread should sleep before "runs" of examining
103 * idle objects. When non-positive, no eviction thread will be launched.
104 * </li>
105 * <li>
106 * {@link #setMinEvictableIdleTimeMillis <i>minEvictableIdleTimeMillis</i>}
107 * specifies the minimum amount of time that an object may sit idle in the pool
108 * before it is eligable for eviction due to idle time. When non-positive, no object
109 * will be dropped from the pool due to idle time alone.
110 * </li>
111 * <li>
112 * {@link #setTestWhileIdle <i>testWhileIdle</i>} indicates whether or not idle
113 * objects should be validated using the factory's
114 * {@link PoolableObjectFactory#validateObject} method. Objects
115 * that fail to validate will be dropped from the pool.
116 * </li>
117 * </ul>
118 * <p>
119 * GenericObjectPool is not usable without a {@link PoolableObjectFactory}. A
120 * non-<code>null</code> factory must be provided either as a constructor argument
121 * or via a call to {@link #setFactory} before the pool is used.
122 *
123 * @see GenericKeyedObjectPool
124 * @author Rodney Waldhoff
125 * @author Dirk Verbeeck
126 * @version $Revision: 390563 $ $Date: 2006-03-31 20:28:14 -0500 (Fri, 31 Mar 2006) $
127 */
128 public class GenericObjectPool extends BaseObjectPool implements ObjectPool {
129
130
131
132 /***
133 * A "when exhausted action" type indicating that when the pool is
134 * exhausted (i.e., the maximum number of active objects has
135 * been reached), the {@link #borrowObject}
136 * method should fail, throwing a {@link NoSuchElementException}.
137 * @see #WHEN_EXHAUSTED_BLOCK
138 * @see #WHEN_EXHAUSTED_GROW
139 * @see #setWhenExhaustedAction
140 */
141 public static final byte WHEN_EXHAUSTED_FAIL = 0;
142
143 /***
144 * A "when exhausted action" type indicating that when the pool
145 * is exhausted (i.e., the maximum number
146 * of active objects has been reached), the {@link #borrowObject}
147 * method should block until a new object is available, or the
148 * {@link #getMaxWait maximum wait time} has been reached.
149 * @see #WHEN_EXHAUSTED_FAIL
150 * @see #WHEN_EXHAUSTED_GROW
151 * @see #setMaxWait
152 * @see #getMaxWait
153 * @see #setWhenExhaustedAction
154 */
155 public static final byte WHEN_EXHAUSTED_BLOCK = 1;
156
157 /***
158 * A "when exhausted action" type indicating that when the pool is
159 * exhausted (i.e., the maximum number
160 * of active objects has been reached), the {@link #borrowObject}
161 * method should simply create a new object anyway.
162 * @see #WHEN_EXHAUSTED_FAIL
163 * @see #WHEN_EXHAUSTED_GROW
164 * @see #setWhenExhaustedAction
165 */
166 public static final byte WHEN_EXHAUSTED_GROW = 2;
167
168 /***
169 * The default cap on the number of "sleeping" instances in the pool.
170 * @see #getMaxIdle
171 * @see #setMaxIdle
172 */
173 public static final int DEFAULT_MAX_IDLE = 8;
174
175 /***
176 * The default minimum number of "sleeping" instances in the pool
177 * before before the evictor thread (if active) spawns new objects.
178 * @see #getMinIdle
179 * @see #setMinIdle
180 */
181 public static final int DEFAULT_MIN_IDLE = 0;
182
183 /***
184 * The default cap on the total number of active instances from the pool.
185 * @see #getMaxActive
186 */
187 public static final int DEFAULT_MAX_ACTIVE = 8;
188
189 /***
190 * The default "when exhausted action" for the pool.
191 * @see #WHEN_EXHAUSTED_BLOCK
192 * @see #WHEN_EXHAUSTED_FAIL
193 * @see #WHEN_EXHAUSTED_GROW
194 * @see #setWhenExhaustedAction
195 */
196 public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
197
198 /***
199 * The default maximum amount of time (in millis) the
200 * {@link #borrowObject} method should block before throwing
201 * an exception when the pool is exhausted and the
202 * {@link #getWhenExhaustedAction "when exhausted" action} is
203 * {@link #WHEN_EXHAUSTED_BLOCK}.
204 * @see #getMaxWait
205 * @see #setMaxWait
206 */
207 public static final long DEFAULT_MAX_WAIT = -1L;
208
209 /***
210 * The default "test on borrow" value.
211 * @see #getTestOnBorrow
212 * @see #setTestOnBorrow
213 */
214 public static final boolean DEFAULT_TEST_ON_BORROW = false;
215
216 /***
217 * The default "test on return" value.
218 * @see #getTestOnReturn
219 * @see #setTestOnReturn
220 */
221 public static final boolean DEFAULT_TEST_ON_RETURN = false;
222
223 /***
224 * The default "test while idle" value.
225 * @see #getTestWhileIdle
226 * @see #setTestWhileIdle
227 * @see #getTimeBetweenEvictionRunsMillis
228 * @see #setTimeBetweenEvictionRunsMillis
229 */
230 public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
231
232 /***
233 * The default "time between eviction runs" value.
234 * @see #getTimeBetweenEvictionRunsMillis
235 * @see #setTimeBetweenEvictionRunsMillis
236 */
237 public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
238
239 /***
240 * The default number of objects to examine per run in the
241 * idle object evictor.
242 * @see #getNumTestsPerEvictionRun
243 * @see #setNumTestsPerEvictionRun
244 * @see #getTimeBetweenEvictionRunsMillis
245 * @see #setTimeBetweenEvictionRunsMillis
246 */
247 public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
248
249 /***
250 * The default value for {@link #getMinEvictableIdleTimeMillis}.
251 * @see #getMinEvictableIdleTimeMillis
252 * @see #setMinEvictableIdleTimeMillis
253 */
254 public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
255
256 /***
257 * The default value for {@link #getSoftMinEvictableIdleTimeMillis}.
258 * @see #getSoftMinEvictableIdleTimeMillis
259 * @see #setSoftMinEvictableIdleTimeMillis
260 */
261 public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
262
263
264
265 /***
266 * Idle object evition Timer. Shared between all {@link GenericObjectPool}s and {@link GenericKeyedObjectPool} s.
267 */
268 static final Timer EVICTION_TIMER = new Timer(true);
269
270
271
272 /***
273 * Create a new <tt>GenericObjectPool</tt>.
274 */
275 public GenericObjectPool() {
276 this(null,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_MIN_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);
277 }
278
279 /***
280 * Create a new <tt>GenericObjectPool</tt> using the specified values.
281 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
282 */
283 public GenericObjectPool(PoolableObjectFactory factory) {
284 this(factory,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_MIN_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);
285 }
286
287 /***
288 * Create a new <tt>GenericObjectPool</tt> using the specified values.
289 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
290 * @param config a non-<tt>null</tt> {@link GenericObjectPool.Config} describing my configuration
291 */
292 public GenericObjectPool(PoolableObjectFactory factory, GenericObjectPool.Config config) {
293 this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.minIdle,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle);
294 }
295
296 /***
297 * Create a new <tt>GenericObjectPool</tt> using the specified values.
298 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
299 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
300 */
301 public GenericObjectPool(PoolableObjectFactory factory, int maxActive) {
302 this(factory,maxActive,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_MIN_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);
303 }
304
305 /***
306 * Create a new <tt>GenericObjectPool</tt> using the specified values.
307 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
308 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
309 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #getWhenExhaustedAction})
310 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
311 */
312 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
313 this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,DEFAULT_MIN_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);
314 }
315
316 /***
317 * Create a new <tt>GenericObjectPool</tt> using the specified values.
318 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
319 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
320 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #getWhenExhaustedAction})
321 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
322 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #getTestOnBorrow})
323 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #getTestOnReturn})
324 */
325 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) {
326 this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,DEFAULT_MIN_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);
327 }
328
329 /***
330 * Create a new <tt>GenericObjectPool</tt> using the specified values.
331 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
332 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
333 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #getWhenExhaustedAction})
334 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
335 * @param maxIdle the maximum number of idle objects in my pool (see {@link #getMaxIdle})
336 */
337 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
338 this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,DEFAULT_MIN_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);
339 }
340
341 /***
342 * Create a new <tt>GenericObjectPool</tt> using the specified values.
343 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
344 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
345 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #getWhenExhaustedAction})
346 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
347 * @param maxIdle the maximum number of idle objects in my pool (see {@link #getMaxIdle})
348 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #getTestOnBorrow})
349 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #getTestOnReturn})
350 */
351 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
352 this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,DEFAULT_MIN_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);
353 }
354
355 /***
356 * Create a new <tt>GenericObjectPool</tt> using the specified values.
357 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
358 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
359 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
360 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
361 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
362 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
363 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
364 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
365 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
366 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
367 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
368 */
369 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
370 this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
371 }
372
373 /***
374 * Create a new <tt>GenericObjectPool</tt> using the specified values.
375 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
376 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
377 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
378 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
379 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
380 * @param minIdle the minimum number of idle objects in my pool (see {@link #setMinIdle})
381 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
382 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
383 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
384 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
385 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
386 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
387 */
388 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
389 this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
390 }
391
392 /***
393 * Create a new <tt>GenericObjectPool</tt> using the specified values.
394 * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
395 * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
396 * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
397 * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
398 * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
399 * @param minIdle the minimum number of idle objects in my pool (see {@link #setMinIdle})
400 * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
401 * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
402 * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
403 * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
404 * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
405 * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
406 * @param softMinEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition with the extra condition that at least "minIdle" amount of object remain in the pool. (see {@link #setSoftMinEvictableIdleTimeMillis})
407 */
408 public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, long softMinEvictableIdleTimeMillis) {
409 _factory = factory;
410 _maxActive = maxActive;
411 switch(whenExhaustedAction) {
412 case WHEN_EXHAUSTED_BLOCK:
413 case WHEN_EXHAUSTED_FAIL:
414 case WHEN_EXHAUSTED_GROW:
415 _whenExhaustedAction = whenExhaustedAction;
416 break;
417 default:
418 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
419 }
420 _maxWait = maxWait;
421 _maxIdle = maxIdle;
422 _minIdle = minIdle;
423 _testOnBorrow = testOnBorrow;
424 _testOnReturn = testOnReturn;
425 _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
426 _numTestsPerEvictionRun = numTestsPerEvictionRun;
427 _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
428 _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
429 _testWhileIdle = testWhileIdle;
430
431 _pool = new LinkedList();
432 startEvictor(_timeBetweenEvictionRunsMillis);
433 }
434
435
436
437
438
439 /***
440 * Returns the cap on the total number of active instances from my pool.
441 * @return the cap on the total number of active instances from my pool.
442 * @see #setMaxActive
443 */
444 public synchronized int getMaxActive() {
445 return _maxActive;
446 }
447
448 /***
449 * Sets the cap on the total number of active instances from my pool.
450 * @param maxActive The cap on the total number of active instances from my pool.
451 * Use a negative value for an infinite number of instances.
452 * @see #getMaxActive
453 */
454 public synchronized void setMaxActive(int maxActive) {
455 _maxActive = maxActive;
456 notifyAll();
457 }
458
459 /***
460 * Returns the action to take when the {@link #borrowObject} method
461 * is invoked when the pool is exhausted (the maximum number
462 * of "active" objects has been reached).
463 *
464 * @return one of {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
465 * @see #setWhenExhaustedAction
466 */
467 public synchronized byte getWhenExhaustedAction() {
468 return _whenExhaustedAction;
469 }
470
471 /***
472 * Sets the action to take when the {@link #borrowObject} method
473 * is invoked when the pool is exhausted (the maximum number
474 * of "active" objects has been reached).
475 *
476 * @param whenExhaustedAction the action code, which must be one of
477 * {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
478 * or {@link #WHEN_EXHAUSTED_GROW}
479 * @see #getWhenExhaustedAction
480 */
481 public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
482 switch(whenExhaustedAction) {
483 case WHEN_EXHAUSTED_BLOCK:
484 case WHEN_EXHAUSTED_FAIL:
485 case WHEN_EXHAUSTED_GROW:
486 _whenExhaustedAction = whenExhaustedAction;
487 notifyAll();
488 break;
489 default:
490 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
491 }
492 }
493
494
495 /***
496 * Returns the maximum amount of time (in milliseconds) the
497 * {@link #borrowObject} method should block before throwing
498 * an exception when the pool is exhausted and the
499 * {@link #setWhenExhaustedAction "when exhausted" action} is
500 * {@link #WHEN_EXHAUSTED_BLOCK}.
501 *
502 * When less than 0, the {@link #borrowObject} method
503 * may block indefinitely.
504 *
505 * @see #setMaxWait
506 * @see #setWhenExhaustedAction
507 * @see #WHEN_EXHAUSTED_BLOCK
508 */
509 public synchronized long getMaxWait() {
510 return _maxWait;
511 }
512
513 /***
514 * Sets the maximum amount of time (in milliseconds) the
515 * {@link #borrowObject} method should block before throwing
516 * an exception when the pool is exhausted and the
517 * {@link #setWhenExhaustedAction "when exhausted" action} is
518 * {@link #WHEN_EXHAUSTED_BLOCK}.
519 *
520 * When less than 0, the {@link #borrowObject} method
521 * may block indefinitely.
522 *
523 * @see #getMaxWait
524 * @see #setWhenExhaustedAction
525 * @see #WHEN_EXHAUSTED_BLOCK
526 */
527 public synchronized void setMaxWait(long maxWait) {
528 _maxWait = maxWait;
529 notifyAll();
530 }
531
532 /***
533 * Returns the cap on the number of "idle" instances in the pool.
534 * @return the cap on the number of "idle" instances in the pool.
535 * @see #setMaxIdle
536 */
537 public synchronized int getMaxIdle() {
538 return _maxIdle;
539 }
540
541 /***
542 * Sets the cap on the number of "idle" instances in the pool.
543 * @param maxIdle The cap on the number of "idle" instances in the pool.
544 * Use a negative value to indicate an unlimited number
545 * of idle instances.
546 * @see #getMaxIdle
547 */
548 public synchronized void setMaxIdle(int maxIdle) {
549 _maxIdle = maxIdle;
550 notifyAll();
551 }
552
553 /***
554 * Sets the minimum number of objects allowed in the pool
555 * before the evictor thread (if active) spawns new objects.
556 * (Note no objects are created when: numActive + numIdle >= maxActive)
557 *
558 * @param minIdle The minimum number of objects.
559 * @see #getMinIdle
560 */
561 public synchronized void setMinIdle(int minIdle) {
562 _minIdle = minIdle;
563 notifyAll();
564 }
565
566 /***
567 * Returns the minimum number of objects allowed in the pool
568 * before the evictor thread (if active) spawns new objects.
569 * (Note no objects are created when: numActive + numIdle >= maxActive)
570 *
571 * @return The minimum number of objects.
572 * @see #setMinIdle
573 */
574 public synchronized int getMinIdle() {
575 return _minIdle;
576 }
577
578 /***
579 * When <tt>true</tt>, objects will be
580 * {@link PoolableObjectFactory#validateObject validated}
581 * before being returned by the {@link #borrowObject}
582 * method. If the object fails to validate,
583 * it will be dropped from the pool, and we will attempt
584 * to borrow another.
585 *
586 * @see #setTestOnBorrow
587 */
588 public synchronized boolean getTestOnBorrow() {
589 return _testOnBorrow;
590 }
591
592 /***
593 * When <tt>true</tt>, objects will be
594 * {@link PoolableObjectFactory#validateObject validated}
595 * before being returned by the {@link #borrowObject}
596 * method. If the object fails to validate,
597 * it will be dropped from the pool, and we will attempt
598 * to borrow another.
599 *
600 * @see #getTestOnBorrow
601 */
602 public synchronized void setTestOnBorrow(boolean testOnBorrow) {
603 _testOnBorrow = testOnBorrow;
604 }
605
606 /***
607 * When <tt>true</tt>, objects will be
608 * {@link PoolableObjectFactory#validateObject validated}
609 * before being returned to the pool within the
610 * {@link #returnObject}.
611 *
612 * @see #setTestOnReturn
613 */
614 public synchronized boolean getTestOnReturn() {
615 return _testOnReturn;
616 }
617
618 /***
619 * When <tt>true</tt>, objects will be
620 * {@link PoolableObjectFactory#validateObject validated}
621 * before being returned to the pool within the
622 * {@link #returnObject}.
623 *
624 * @see #getTestOnReturn
625 */
626 public synchronized void setTestOnReturn(boolean testOnReturn) {
627 _testOnReturn = testOnReturn;
628 }
629
630 /***
631 * Returns the number of milliseconds to sleep between runs of the
632 * idle object evictor thread.
633 * When non-positive, no idle object evictor thread will be
634 * run.
635 *
636 * @see #setTimeBetweenEvictionRunsMillis
637 */
638 public synchronized long getTimeBetweenEvictionRunsMillis() {
639 return _timeBetweenEvictionRunsMillis;
640 }
641
642 /***
643 * Sets the number of milliseconds to sleep between runs of the
644 * idle object evictor thread.
645 * When non-positive, no idle object evictor thread will be
646 * run.
647 *
648 * @see #getTimeBetweenEvictionRunsMillis
649 */
650 public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
651 _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
652 startEvictor(_timeBetweenEvictionRunsMillis);
653 }
654
655 /***
656 * Returns the max number of objects to examine during each run of the
657 * idle object evictor thread (if any).
658 *
659 * @see #setNumTestsPerEvictionRun
660 * @see #setTimeBetweenEvictionRunsMillis
661 */
662 public synchronized int getNumTestsPerEvictionRun() {
663 return _numTestsPerEvictionRun;
664 }
665
666 /***
667 * Sets the max number of objects to examine during each run of the
668 * idle object evictor thread (if any).
669 * <p>
670 * When a negative value is supplied, <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
671 * tests will be run. I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
672 * idle objects will be tested per run.
673 *
674 * @see #getNumTestsPerEvictionRun
675 * @see #setTimeBetweenEvictionRunsMillis
676 */
677 public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
678 _numTestsPerEvictionRun = numTestsPerEvictionRun;
679 }
680
681 /***
682 * Returns the minimum amount of time an object may sit idle in the pool
683 * before it is eligable for eviction by the idle object evictor
684 * (if any).
685 *
686 * @see #setMinEvictableIdleTimeMillis
687 * @see #setTimeBetweenEvictionRunsMillis
688 */
689 public synchronized long getMinEvictableIdleTimeMillis() {
690 return _minEvictableIdleTimeMillis;
691 }
692
693 /***
694 * Sets the minimum amount of time an object may sit idle in the pool
695 * before it is eligable for eviction by the idle object evictor
696 * (if any).
697 * When non-positive, no objects will be evicted from the pool
698 * due to idle time alone.
699 *
700 * @see #getMinEvictableIdleTimeMillis
701 * @see #setTimeBetweenEvictionRunsMillis
702 */
703 public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
704 _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
705 }
706
707 /***
708 * Returns the minimum amount of time an object may sit idle in the pool
709 * before it is eligable for eviction by the idle object evictor
710 * (if any), with the extra condition that at least
711 * "minIdle" amount of object remain in the pool.
712 *
713 * @see #setSoftMinEvictableIdleTimeMillis
714 */
715 public synchronized long getSoftMinEvictableIdleTimeMillis() {
716 return _softMinEvictableIdleTimeMillis;
717 }
718
719 /***
720 * Sets the minimum amount of time an object may sit idle in the pool
721 * before it is eligable for eviction by the idle object evictor
722 * (if any), with the extra condition that at least
723 * "minIdle" amount of object remain in the pool.
724 * When non-positive, no objects will be evicted from the pool
725 * due to idle time alone.
726 *
727 * @see #getSoftMinEvictableIdleTimeMillis
728 */
729 public synchronized void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) {
730 _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
731 }
732
733 /***
734 * When <tt>true</tt>, objects will be
735 * {@link PoolableObjectFactory#validateObject validated}
736 * by the idle object evictor (if any). If an object
737 * fails to validate, it will be dropped from the pool.
738 *
739 * @see #setTestWhileIdle
740 * @see #setTimeBetweenEvictionRunsMillis
741 */
742 public synchronized boolean getTestWhileIdle() {
743 return _testWhileIdle;
744 }
745
746 /***
747 * When <tt>true</tt>, objects will be
748 * {@link PoolableObjectFactory#validateObject validated}
749 * by the idle object evictor (if any). If an object
750 * fails to validate, it will be dropped from the pool.
751 *
752 * @see #getTestWhileIdle
753 * @see #setTimeBetweenEvictionRunsMillis
754 */
755 public synchronized void setTestWhileIdle(boolean testWhileIdle) {
756 _testWhileIdle = testWhileIdle;
757 }
758
759 /***
760 * Sets my configuration.
761 * @see GenericObjectPool.Config
762 */
763 public synchronized void setConfig(GenericObjectPool.Config conf) {
764 setMaxIdle(conf.maxIdle);
765 setMinIdle(conf.minIdle);
766 setMaxActive(conf.maxActive);
767 setMaxWait(conf.maxWait);
768 setWhenExhaustedAction(conf.whenExhaustedAction);
769 setTestOnBorrow(conf.testOnBorrow);
770 setTestOnReturn(conf.testOnReturn);
771 setTestWhileIdle(conf.testWhileIdle);
772 setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
773 setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
774 setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
775 notifyAll();
776 }
777
778
779
780 public synchronized Object borrowObject() throws Exception {
781 assertOpen();
782 long starttime = System.currentTimeMillis();
783 for(;;) {
784 ObjectTimestampPair pair = null;
785
786
787 try {
788 pair = (ObjectTimestampPair)(_pool.removeFirst());
789 } catch(NoSuchElementException e) {
790 ;
791 }
792
793
794 if(null == pair) {
795
796
797 if(_maxActive < 0 || _numActive < _maxActive) {
798
799 } else {
800
801 switch(_whenExhaustedAction) {
802 case WHEN_EXHAUSTED_GROW:
803
804 break;
805 case WHEN_EXHAUSTED_FAIL:
806 throw new NoSuchElementException("Pool exhausted");
807 case WHEN_EXHAUSTED_BLOCK:
808 try {
809 if(_maxWait <= 0) {
810 wait();
811 } else {
812
813
814 final long elapsed = (System.currentTimeMillis() - starttime);
815 final long waitTime = _maxWait - elapsed;
816 if (waitTime > 0)
817 {
818 wait(waitTime);
819 }
820 }
821 } catch(InterruptedException e) {
822
823 }
824 if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
825 throw new NoSuchElementException("Timeout waiting for idle object");
826 } else {
827 continue;
828 }
829 default:
830 throw new IllegalArgumentException("WhenExhaustedAction property " + _whenExhaustedAction + " not recognized.");
831 }
832 }
833 }
834 _numActive++;
835
836
837 boolean newlyCreated = false;
838 if(null == pair) {
839 try {
840 Object obj = _factory.makeObject();
841 pair = new ObjectTimestampPair(obj);
842 newlyCreated = true;
843 } finally {
844 if (!newlyCreated) {
845
846 _numActive--;
847 notifyAll();
848 }
849 }
850 }
851
852
853 try {
854 _factory.activateObject(pair.value);
855 if(_testOnBorrow && !_factory.validateObject(pair.value)) {
856 throw new Exception("ValidateObject failed");
857 }
858 return pair.value;
859 }
860 catch (Throwable e) {
861
862 _numActive--;
863 notifyAll();
864 try {
865 _factory.destroyObject(pair.value);
866 }
867 catch (Throwable e2) {
868
869 }
870 if(newlyCreated) {
871 throw new NoSuchElementException("Could not create a validated object, cause: " + e.getMessage());
872 }
873 else {
874 continue;
875 }
876 }
877 }
878 }
879
880 public synchronized void invalidateObject(Object obj) throws Exception {
881 assertOpen();
882 try {
883 _factory.destroyObject(obj);
884 }
885 finally {
886 _numActive--;
887 notifyAll();
888 }
889 }
890
891 public synchronized void clear() {
892 assertOpen();
893 for(Iterator it = _pool.iterator(); it.hasNext(); ) {
894 try {
895 _factory.destroyObject(((ObjectTimestampPair)(it.next())).value);
896 } catch(Exception e) {
897
898 }
899 it.remove();
900 }
901 _pool.clear();
902 notifyAll();
903 }
904
905 public synchronized int getNumActive() {
906 assertOpen();
907 return _numActive;
908 }
909
910 public synchronized int getNumIdle() {
911 assertOpen();
912 return _pool.size();
913 }
914
915 public synchronized void returnObject(Object obj) throws Exception {
916 assertOpen();
917 addObjectToPool(obj, true);
918 }
919
920 private void addObjectToPool(Object obj, boolean decrementNumActive) throws Exception {
921 boolean success = true;
922 if(_testOnReturn && !(_factory.validateObject(obj))) {
923 success = false;
924 } else {
925 try {
926 _factory.passivateObject(obj);
927 } catch(Exception e) {
928 success = false;
929 }
930 }
931
932 boolean shouldDestroy = !success;
933
934 if (decrementNumActive) {
935 _numActive--;
936 }
937 if((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {
938 shouldDestroy = true;
939 } else if(success) {
940 _pool.addLast(new ObjectTimestampPair(obj));
941 }
942 notifyAll();
943
944 if(shouldDestroy) {
945 try {
946 _factory.destroyObject(obj);
947 } catch(Exception e) {
948
949 }
950 }
951 }
952
953 public synchronized void close() throws Exception {
954 clear();
955 _pool = null;
956 _factory = null;
957 startEvictor(-1L);
958 super.close();
959 }
960
961 public synchronized void setFactory(PoolableObjectFactory factory) throws IllegalStateException {
962 assertOpen();
963 if(0 < getNumActive()) {
964 throw new IllegalStateException("Objects are already active");
965 } else {
966 clear();
967 _factory = factory;
968 }
969 }
970
971 public synchronized void evict() throws Exception {
972 assertOpen();
973 if(!_pool.isEmpty()) {
974 ListIterator iter;
975 if (evictLastIndex < 0) {
976 iter = _pool.listIterator(_pool.size());
977 } else {
978 iter = _pool.listIterator(evictLastIndex);
979 }
980 for(int i=0,m=getNumTests();i<m;i++) {
981 if(!iter.hasPrevious()) {
982 iter = _pool.listIterator(_pool.size());
983 }
984 boolean removeObject = false;
985 final ObjectTimestampPair pair = (ObjectTimestampPair)(iter.previous());
986 final long idleTimeMilis = System.currentTimeMillis() - pair.tstamp;
987 if ((_minEvictableIdleTimeMillis > 0)
988 && (idleTimeMilis > _minEvictableIdleTimeMillis)) {
989 removeObject = true;
990 } else if ((_softMinEvictableIdleTimeMillis > 0)
991 && (idleTimeMilis > _softMinEvictableIdleTimeMillis)
992 && (getNumIdle() > getMinIdle())) {
993 removeObject = true;
994 }
995 if(_testWhileIdle && !removeObject) {
996 boolean active = false;
997 try {
998 _factory.activateObject(pair.value);
999 active = true;
1000 } catch(Exception e) {
1001 removeObject=true;
1002 }
1003 if(active) {
1004 if(!_factory.validateObject(pair.value)) {
1005 removeObject=true;
1006 } else {
1007 try {
1008 _factory.passivateObject(pair.value);
1009 } catch(Exception e) {
1010 removeObject=true;
1011 }
1012 }
1013 }
1014 }
1015 if(removeObject) {
1016 try {
1017 iter.remove();
1018 _factory.destroyObject(pair.value);
1019 } catch(Exception e) {
1020
1021 }
1022 }
1023 }
1024 evictLastIndex = iter.previousIndex();
1025 }
1026 }
1027
1028 /***
1029 * Check to see if we are below our minimum number of objects
1030 * if so enough to bring us back to our minimum.
1031 */
1032 private void ensureMinIdle() throws Exception {
1033
1034
1035
1036
1037
1038 int objectDeficit = calculateDeficit();
1039 for ( int j = 0 ; j < objectDeficit && calculateDeficit() > 0 ; j++ ) {
1040 addObject();
1041 }
1042 }
1043
1044 private synchronized int calculateDeficit() {
1045 int objectDeficit = getMinIdle() - getNumIdle();
1046 if (_maxActive > 0) {
1047 int growLimit = Math.max(0, getMaxActive() - getNumActive() - getNumIdle());
1048 objectDeficit = Math.min(objectDeficit, growLimit);
1049 }
1050 return objectDeficit;
1051 }
1052
1053 /***
1054 * Create an object, and place it into the pool.
1055 * addObject() is useful for "pre-loading" a pool with idle objects.
1056 */
1057 public synchronized void addObject() throws Exception {
1058 assertOpen();
1059 Object obj = _factory.makeObject();
1060 addObjectToPool(obj, false);
1061 }
1062
1063
1064
1065 /***
1066 * Start the eviction thread or service, or when
1067 * <i>delay</i> is non-positive, stop it
1068 * if it is already running.
1069 */
1070 protected synchronized void startEvictor(long delay) {
1071 if(null != _evictor) {
1072 _evictor.cancel();
1073 _evictor = null;
1074 }
1075 if(delay > 0) {
1076 _evictor = new Evictor();
1077 EVICTION_TIMER.schedule(_evictor, delay, delay);
1078 }
1079 }
1080
1081 synchronized String debugInfo() {
1082 StringBuffer buf = new StringBuffer();
1083 buf.append("Active: ").append(getNumActive()).append("\n");
1084 buf.append("Idle: ").append(getNumIdle()).append("\n");
1085 buf.append("Idle Objects:\n");
1086 Iterator it = _pool.iterator();
1087 long time = System.currentTimeMillis();
1088 while(it.hasNext()) {
1089 ObjectTimestampPair pair = (ObjectTimestampPair)(it.next());
1090 buf.append("\t").append(pair.value).append("\t").append(time - pair.tstamp).append("\n");
1091 }
1092 return buf.toString();
1093 }
1094
1095 private int getNumTests() {
1096 if(_numTestsPerEvictionRun >= 0) {
1097 return Math.min(_numTestsPerEvictionRun, _pool.size());
1098 } else {
1099 return(int)(Math.ceil((double)_pool.size()/Math.abs((double)_numTestsPerEvictionRun)));
1100 }
1101 }
1102
1103
1104
1105 /***
1106 * The idle object evictor {@link TimerTask}.
1107 * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
1108 */
1109 private class Evictor extends TimerTask {
1110 public void run() {
1111 try {
1112 evict();
1113 } catch(Exception e) {
1114
1115 }
1116 try {
1117 ensureMinIdle();
1118 } catch(Exception e) {
1119
1120 }
1121 }
1122 }
1123
1124 /***
1125 * A simple "struct" encapsulating the
1126 * configuration information for a {@link GenericObjectPool}.
1127 * @see GenericObjectPool#GenericObjectPool(org.apache.commons.pool.PoolableObjectFactory,org.apache.commons.pool.impl.GenericObjectPool.Config)
1128 * @see GenericObjectPool#setConfig
1129 */
1130 public static class Config {
1131 public int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
1132 public int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;
1133 public int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
1134 public long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;
1135 public byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
1136 public boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;
1137 public boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;
1138 public boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;
1139 public long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1140 public int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1141 public long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1142 public long softMinEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1143 }
1144
1145
1146
1147 /***
1148 * The cap on the number of idle instances in the pool.
1149 * @see #setMaxIdle
1150 * @see #getMaxIdle
1151 */
1152 private int _maxIdle = DEFAULT_MAX_IDLE;
1153
1154 /***
1155 * The cap on the minimum number of idle instances in the pool.
1156 * @see #setMinIdle
1157 * @see #getMinIdle
1158 */
1159 private int _minIdle = DEFAULT_MIN_IDLE;
1160
1161 /***
1162 * The cap on the total number of active instances from the pool.
1163 * @see #setMaxActive
1164 * @see #getMaxActive
1165 */
1166 private int _maxActive = DEFAULT_MAX_ACTIVE;
1167
1168 /***
1169 * The maximum amount of time (in millis) the
1170 * {@link #borrowObject} method should block before throwing
1171 * an exception when the pool is exhausted and the
1172 * {@link #getWhenExhaustedAction "when exhausted" action} is
1173 * {@link #WHEN_EXHAUSTED_BLOCK}.
1174 *
1175 * When less than 0, the {@link #borrowObject} method
1176 * may block indefinitely.
1177 *
1178 * @see #setMaxWait
1179 * @see #getMaxWait
1180 * @see #WHEN_EXHAUSTED_BLOCK
1181 * @see #setWhenExhaustedAction
1182 * @see #getWhenExhaustedAction
1183 */
1184 private long _maxWait = DEFAULT_MAX_WAIT;
1185
1186 /***
1187 * The action to take when the {@link #borrowObject} method
1188 * is invoked when the pool is exhausted (the maximum number
1189 * of "active" objects has been reached).
1190 *
1191 * @see #WHEN_EXHAUSTED_BLOCK
1192 * @see #WHEN_EXHAUSTED_FAIL
1193 * @see #WHEN_EXHAUSTED_GROW
1194 * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
1195 * @see #setWhenExhaustedAction
1196 * @see #getWhenExhaustedAction
1197 */
1198 private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
1199
1200 /***
1201 * When <tt>true</tt>, objects will be
1202 * {@link PoolableObjectFactory#validateObject validated}
1203 * before being returned by the {@link #borrowObject}
1204 * method. If the object fails to validate,
1205 * it will be dropped from the pool, and we will attempt
1206 * to borrow another.
1207 *
1208 * @see #setTestOnBorrow
1209 * @see #getTestOnBorrow
1210 */
1211 private boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
1212
1213 /***
1214 * When <tt>true</tt>, objects will be
1215 * {@link PoolableObjectFactory#validateObject validated}
1216 * before being returned to the pool within the
1217 * {@link #returnObject}.
1218 *
1219 * @see #getTestOnReturn
1220 * @see #setTestOnReturn
1221 */
1222 private boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
1223
1224 /***
1225 * When <tt>true</tt>, objects will be
1226 * {@link PoolableObjectFactory#validateObject validated}
1227 * by the idle object evictor (if any). If an object
1228 * fails to validate, it will be dropped from the pool.
1229 *
1230 * @see #setTestWhileIdle
1231 * @see #getTestWhileIdle
1232 * @see #getTimeBetweenEvictionRunsMillis
1233 * @see #setTimeBetweenEvictionRunsMillis
1234 */
1235 private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
1236
1237 /***
1238 * The number of milliseconds to sleep between runs of the
1239 * idle object evictor thread.
1240 * When non-positive, no idle object evictor thread will be
1241 * run.
1242 *
1243 * @see #setTimeBetweenEvictionRunsMillis
1244 * @see #getTimeBetweenEvictionRunsMillis
1245 */
1246 private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1247
1248 /***
1249 * The max number of objects to examine during each run of the
1250 * idle object evictor thread (if any).
1251 * <p>
1252 * When a negative value is supplied, <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
1253 * tests will be run. I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
1254 * idle objects will be tested per run.
1255 *
1256 * @see #setNumTestsPerEvictionRun
1257 * @see #getNumTestsPerEvictionRun
1258 * @see #getTimeBetweenEvictionRunsMillis
1259 * @see #setTimeBetweenEvictionRunsMillis
1260 */
1261 private int _numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1262
1263 /***
1264 * The minimum amount of time an object may sit idle in the pool
1265 * before it is eligable for eviction by the idle object evictor
1266 * (if any).
1267 * When non-positive, no objects will be evicted from the pool
1268 * due to idle time alone.
1269 *
1270 * @see #setMinEvictableIdleTimeMillis
1271 * @see #getMinEvictableIdleTimeMillis
1272 * @see #getTimeBetweenEvictionRunsMillis
1273 * @see #setTimeBetweenEvictionRunsMillis
1274 */
1275 private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1276
1277 /***
1278 * The minimum amount of time an object may sit idle in the pool
1279 * before it is eligable for eviction by the idle object evictor
1280 * (if any), with the extra condition that at least
1281 * "minIdle" amount of object remain in the pool.
1282 * When non-positive, no objects will be evicted from the pool
1283 * due to idle time alone.
1284 *
1285 * @see #setSoftMinEvictableIdleTimeMillis
1286 * @see #getSoftMinEvictableIdleTimeMillis
1287 */
1288 private long _softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1289
1290 /*** My pool. */
1291 private LinkedList _pool = null;
1292
1293 /*** My {@link PoolableObjectFactory}. */
1294 private PoolableObjectFactory _factory = null;
1295
1296 /***
1297 * The number of objects {@link #borrowObject} borrowed
1298 * from the pool, but not yet returned.
1299 */
1300 private int _numActive = 0;
1301
1302 /***
1303 * My idle object eviction {@link TimerTask}, if any.
1304 */
1305 private Evictor _evictor = null;
1306
1307 /***
1308 * Position in the _pool where the _evictor last stopped.
1309 */
1310 private int evictLastIndex = -1;
1311 }