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