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