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