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