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