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 */ 017package org.apache.commons.pool2.impl; 018 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.io.Writer; 022import java.lang.management.ManagementFactory; 023import java.lang.ref.WeakReference; 024import java.util.Iterator; 025import java.util.TimerTask; 026import java.util.concurrent.atomic.AtomicLong; 027 028import javax.management.InstanceAlreadyExistsException; 029import javax.management.InstanceNotFoundException; 030import javax.management.MBeanRegistrationException; 031import javax.management.MBeanServer; 032import javax.management.MalformedObjectNameException; 033import javax.management.NotCompliantMBeanException; 034import javax.management.ObjectName; 035 036import org.apache.commons.pool2.PooledObject; 037import org.apache.commons.pool2.SwallowedExceptionListener; 038 039/** 040 * Base class that provides common functionality for {@link GenericObjectPool} 041 * and {@link GenericKeyedObjectPool}. The primary reason this class exists is 042 * reduce code duplication between the two pool implementations. 043 * 044 * @param <T> Type of element pooled in this pool. 045 * 046 * This class is intended to be thread-safe. 047 * 048 * @version $Revision: $ 049 * 050 * @since 2.0 051 */ 052public abstract class BaseGenericObjectPool<T> { 053 054 // Constants 055 /** 056 * The size of the caches used to store historical data for some attributes 057 * so that rolling means may be calculated. 058 */ 059 public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100; 060 061 // Configuration attributes 062 private volatile int maxTotal = 063 GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL; 064 private volatile boolean blockWhenExhausted = 065 BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED; 066 private volatile long maxWaitMillis = 067 BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS; 068 private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO; 069 private final boolean fairness; 070 private volatile boolean testOnCreate = 071 BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE; 072 private volatile boolean testOnBorrow = 073 BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW; 074 private volatile boolean testOnReturn = 075 BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN; 076 private volatile boolean testWhileIdle = 077 BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE; 078 private volatile long timeBetweenEvictionRunsMillis = 079 BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; 080 private volatile int numTestsPerEvictionRun = 081 BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; 082 private volatile long minEvictableIdleTimeMillis = 083 BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 084 private volatile long softMinEvictableIdleTimeMillis = 085 BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 086 private volatile EvictionPolicy<T> evictionPolicy; 087 088 089 // Internal (primarily state) attributes 090 final Object closeLock = new Object(); 091 volatile boolean closed = false; 092 final Object evictionLock = new Object(); 093 private Evictor evictor = null; // @GuardedBy("evictionLock") 094 Iterator<PooledObject<T>> evictionIterator = null; // @GuardedBy("evictionLock") 095 /* 096 * Class loader for evictor thread to use since, in a JavaEE or similar 097 * environment, the context class loader for the evictor thread may not have 098 * visibility of the correct factory. See POOL-161. Uses a weak reference to 099 * avoid potential memory leaks if the Pool is discarded rather than closed. 100 */ 101 private final WeakReference<ClassLoader> factoryClassLoader; 102 103 104 // Monitoring (primarily JMX) attributes 105 private final ObjectName oname; 106 private final String creationStackTrace; 107 private final AtomicLong borrowedCount = new AtomicLong(0); 108 private final AtomicLong returnedCount = new AtomicLong(0); 109 final AtomicLong createdCount = new AtomicLong(0); 110 final AtomicLong destroyedCount = new AtomicLong(0); 111 final AtomicLong destroyedByEvictorCount = new AtomicLong(0); 112 final AtomicLong destroyedByBorrowValidationCount = new AtomicLong(0); 113 private final StatsStore activeTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE); 114 private final StatsStore idleTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE); 115 private final StatsStore waitTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE); 116 private final AtomicLong maxBorrowWaitTimeMillis = new AtomicLong(0L); 117 private volatile SwallowedExceptionListener swallowedExceptionListener = null; 118 119 120 /** 121 * Handles JMX registration (if required) and the initialization required for 122 * monitoring. 123 * 124 * @param config Pool configuration 125 * @param jmxNameBase The default base JMX name for the new pool unless 126 * overridden by the config 127 * @param jmxNamePrefix Prefix to be used for JMX name for the new pool 128 */ 129 public BaseGenericObjectPool(BaseObjectPoolConfig config, 130 String jmxNameBase, String jmxNamePrefix) { 131 if (config.getJmxEnabled()) { 132 this.oname = jmxRegister(config, jmxNameBase, jmxNamePrefix); 133 } else { 134 this.oname = null; 135 } 136 137 // Populate the creation stack trace 138 this.creationStackTrace = getStackTrace(new Exception()); 139 140 // save the current TCCL (if any) to be used later by the evictor Thread 141 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 142 if (cl == null) { 143 factoryClassLoader = null; 144 } else { 145 factoryClassLoader = new WeakReference<ClassLoader>(cl); 146 } 147 148 fairness = config.getFairness(); 149 } 150 151 152 /** 153 * Returns the maximum number of objects that can be allocated by the pool 154 * (checked out to clients, or idle awaiting checkout) at a given time. When 155 * negative, there is no limit to the number of objects that can be 156 * managed by the pool at one time. 157 * 158 * @return the cap on the total number of object instances managed by the 159 * pool. 160 * 161 * @see #setMaxTotal 162 */ 163 public final int getMaxTotal() { 164 return maxTotal; 165 } 166 167 /** 168 * Sets the cap on the number of objects that can be allocated by the pool 169 * (checked out to clients, or idle awaiting checkout) at a given time. Use 170 * a negative value for no limit. 171 * 172 * @param maxTotal The cap on the total number of object instances managed 173 * by the pool. Negative values mean that there is no limit 174 * to the number of objects allocated by the pool. 175 * 176 * @see #getMaxTotal 177 */ 178 public final void setMaxTotal(int maxTotal) { 179 this.maxTotal = maxTotal; 180 } 181 182 /** 183 * Returns whether to block when the <code>borrowObject()</code> method is 184 * invoked when the pool is exhausted (the maximum number of "active" 185 * objects has been reached). 186 * 187 * @return <code>true</code> if <code>borrowObject()</code> should block 188 * when the pool is exhausted 189 * 190 * @see #setBlockWhenExhausted 191 */ 192 public final boolean getBlockWhenExhausted() { 193 return blockWhenExhausted; 194 } 195 196 /** 197 * Sets whether to block when the <code>borrowObject()</code> method is 198 * invoked when the pool is exhausted (the maximum number of "active" 199 * objects has been reached). 200 * 201 * @param blockWhenExhausted <code>true</code> if 202 * <code>borrowObject()</code> should block 203 * when the pool is exhausted 204 * 205 * @see #getBlockWhenExhausted 206 */ 207 public final void setBlockWhenExhausted(boolean blockWhenExhausted) { 208 this.blockWhenExhausted = blockWhenExhausted; 209 } 210 211 /** 212 * Returns the maximum amount of time (in milliseconds) the 213 * <code>borrowObject()</code> method should block before throwing an 214 * exception when the pool is exhausted and 215 * {@link #getBlockWhenExhausted} is true. When less than 0, the 216 * <code>borrowObject()</code> method may block indefinitely. 217 * 218 * @return the maximum number of milliseconds <code>borrowObject()</code> 219 * will block. 220 * 221 * @see #setMaxWaitMillis 222 * @see #setBlockWhenExhausted 223 */ 224 public final long getMaxWaitMillis() { 225 return maxWaitMillis; 226 } 227 228 /** 229 * Sets the maximum amount of time (in milliseconds) the 230 * <code>borrowObject()</code> method should block before throwing an 231 * exception when the pool is exhausted and 232 * {@link #getBlockWhenExhausted} is true. When less than 0, the 233 * <code>borrowObject()</code> method may block indefinitely. 234 * 235 * @param maxWaitMillis the maximum number of milliseconds 236 * <code>borrowObject()</code> will block or negative 237 * for indefinitely. 238 * 239 * @see #getMaxWaitMillis 240 * @see #setBlockWhenExhausted 241 */ 242 public final void setMaxWaitMillis(long maxWaitMillis) { 243 this.maxWaitMillis = maxWaitMillis; 244 } 245 246 /** 247 * Returns whether the pool has LIFO (last in, first out) behaviour with 248 * respect to idle objects - always returning the most recently used object 249 * from the pool, or as a FIFO (first in, first out) queue, where the pool 250 * always returns the oldest object in the idle object pool. 251 * 252 * @return <code>true</code> if the pool is configured with LIFO behaviour 253 * or <code>false</code> if the pool is configured with FIFO 254 * behaviour 255 * 256 * @see #setLifo 257 */ 258 public final boolean getLifo() { 259 return lifo; 260 } 261 262 /** 263 * Returns whether or not the pool serves threads waiting to borrow objects fairly. 264 * True means that waiting threads are served as if waiting in a FIFO queue. 265 * 266 * @return <code>true</code> if waiting threads are to be served 267 * by the pool in arrival order 268 */ 269 public final boolean getFairness() { 270 return fairness; 271 } 272 273 /** 274 * Sets whether the pool has LIFO (last in, first out) behaviour with 275 * respect to idle objects - always returning the most recently used object 276 * from the pool, or as a FIFO (first in, first out) queue, where the pool 277 * always returns the oldest object in the idle object pool. 278 * 279 * @param lifo <code>true</code> if the pool is to be configured with LIFO 280 * behaviour or <code>false</code> if the pool is to be 281 * configured with FIFO behaviour 282 * 283 * @see #getLifo() 284 */ 285 public final void setLifo(boolean lifo) { 286 this.lifo = lifo; 287 } 288 289 /** 290 * Returns whether objects created for the pool will be validated before 291 * being returned from the <code>borrowObject()</code> method. Validation is 292 * performed by the <code>validateObject()</code> method of the factory 293 * associated with the pool. If the object fails to validate, then 294 * <code>borrowObject()</code> will fail. 295 * 296 * @return <code>true</code> if newly created objects are validated before 297 * being returned from the <code>borrowObject()</code> method 298 * 299 * @see #setTestOnCreate 300 * 301 * @since 2.2 302 */ 303 public final boolean getTestOnCreate() { 304 return testOnCreate; 305 } 306 307 /** 308 * Sets whether objects created for the pool will be validated before 309 * being returned from the <code>borrowObject()</code> method. Validation is 310 * performed by the <code>validateObject()</code> method of the factory 311 * associated with the pool. If the object fails to validate, then 312 * <code>borrowObject()</code> will fail. 313 * 314 * @param testOnCreate <code>true</code> if newly created objects should be 315 * validated before being returned from the 316 * <code>borrowObject()</code> method 317 * 318 * @see #getTestOnCreate 319 * 320 * @since 2.2 321 */ 322 public final void setTestOnCreate(boolean testOnCreate) { 323 this.testOnCreate = testOnCreate; 324 } 325 326 /** 327 * Returns whether objects borrowed from the pool will be validated before 328 * being returned from the <code>borrowObject()</code> method. Validation is 329 * performed by the <code>validateObject()</code> method of the factory 330 * associated with the pool. If the object fails to validate, it will be 331 * removed from the pool and destroyed, and a new attempt will be made to 332 * borrow an object from the pool. 333 * 334 * @return <code>true</code> if objects are validated before being returned 335 * from the <code>borrowObject()</code> method 336 * 337 * @see #setTestOnBorrow 338 */ 339 public final boolean getTestOnBorrow() { 340 return testOnBorrow; 341 } 342 343 /** 344 * Sets whether objects borrowed from the pool will be validated before 345 * being returned from the <code>borrowObject()</code> method. Validation is 346 * performed by the <code>validateObject()</code> method of the factory 347 * associated with the pool. If the object fails to validate, it will be 348 * removed from the pool and destroyed, and a new attempt will be made to 349 * borrow an object from the pool. 350 * 351 * @param testOnBorrow <code>true</code> if objects should be validated 352 * before being returned from the 353 * <code>borrowObject()</code> method 354 * 355 * @see #getTestOnBorrow 356 */ 357 public final void setTestOnBorrow(boolean testOnBorrow) { 358 this.testOnBorrow = testOnBorrow; 359 } 360 361 /** 362 * Returns whether objects borrowed from the pool will be validated when 363 * they are returned to the pool via the <code>returnObject()</code> method. 364 * Validation is performed by the <code>validateObject()</code> method of 365 * the factory associated with the pool. Returning objects that fail validation 366 * are destroyed rather then being returned the pool. 367 * 368 * @return <code>true</code> if objects are validated on return to 369 * the pool via the <code>returnObject()</code> method 370 * 371 * @see #setTestOnReturn 372 */ 373 public final boolean getTestOnReturn() { 374 return testOnReturn; 375 } 376 377 /** 378 * Sets whether objects borrowed from the pool will be validated when 379 * they are returned to the pool via the <code>returnObject()</code> method. 380 * Validation is performed by the <code>validateObject()</code> method of 381 * the factory associated with the pool. Returning objects that fail validation 382 * are destroyed rather then being returned the pool. 383 * 384 * @param testOnReturn <code>true</code> if objects are validated on 385 * return to the pool via the 386 * <code>returnObject()</code> method 387 * 388 * @see #getTestOnReturn 389 */ 390 public final void setTestOnReturn(boolean testOnReturn) { 391 this.testOnReturn = testOnReturn; 392 } 393 394 /** 395 * Returns whether objects sitting idle in the pool will be validated by the 396 * idle object evictor (if any - see 397 * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed 398 * by the <code>validateObject()</code> method of the factory associated 399 * with the pool. If the object fails to validate, it will be removed from 400 * the pool and destroyed. 401 * 402 * @return <code>true</code> if objects will be validated by the evictor 403 * 404 * @see #setTestWhileIdle 405 * @see #setTimeBetweenEvictionRunsMillis 406 */ 407 public final boolean getTestWhileIdle() { 408 return testWhileIdle; 409 } 410 411 /** 412 * Returns whether objects sitting idle in the pool will be validated by the 413 * idle object evictor (if any - see 414 * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed 415 * by the <code>validateObject()</code> method of the factory associated 416 * with the pool. If the object fails to validate, it will be removed from 417 * the pool and destroyed. Note that setting this property has no effect 418 * unless the idle object evictor is enabled by setting 419 * <code>timeBetweenEvictionRunsMillis</code> to a positive value. 420 * 421 * @param testWhileIdle 422 * <code>true</code> so objects will be validated by the evictor 423 * 424 * @see #getTestWhileIdle 425 * @see #setTimeBetweenEvictionRunsMillis 426 */ 427 public final void setTestWhileIdle(boolean testWhileIdle) { 428 this.testWhileIdle = testWhileIdle; 429 } 430 431 /** 432 * Returns the number of milliseconds to sleep between runs of the idle 433 * object evictor thread. When non-positive, no idle object evictor thread 434 * will be run. 435 * 436 * @return number of milliseconds to sleep between evictor runs 437 * 438 * @see #setTimeBetweenEvictionRunsMillis 439 */ 440 public final long getTimeBetweenEvictionRunsMillis() { 441 return timeBetweenEvictionRunsMillis; 442 } 443 444 /** 445 * Sets the number of milliseconds to sleep between runs of the idle 446 * object evictor thread. When non-positive, no idle object evictor thread 447 * will be run. 448 * 449 * @param timeBetweenEvictionRunsMillis 450 * number of milliseconds to sleep between evictor runs 451 * 452 * @see #getTimeBetweenEvictionRunsMillis 453 */ 454 public final void setTimeBetweenEvictionRunsMillis( 455 long timeBetweenEvictionRunsMillis) { 456 this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 457 startEvictor(timeBetweenEvictionRunsMillis); 458 } 459 460 /** 461 * Returns the maximum number of objects to examine during each run (if any) 462 * of the idle object evictor thread. When positive, the number of tests 463 * performed for a run will be the minimum of the configured value and the 464 * number of idle instances in the pool. When negative, the number of tests 465 * performed will be <code>ceil({@link #getNumIdle}/ 466 * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the 467 * value is <code>-n</code> roughly one nth of the idle objects will be 468 * tested per run. 469 * 470 * @return max number of objects to examine during each evictor run 471 * 472 * @see #setNumTestsPerEvictionRun 473 * @see #setTimeBetweenEvictionRunsMillis 474 */ 475 public final int getNumTestsPerEvictionRun() { 476 return numTestsPerEvictionRun; 477 } 478 479 /** 480 * Sets the maximum number of objects to examine during each run (if any) 481 * of the idle object evictor thread. When positive, the number of tests 482 * performed for a run will be the minimum of the configured value and the 483 * number of idle instances in the pool. When negative, the number of tests 484 * performed will be <code>ceil({@link #getNumIdle}/ 485 * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the 486 * value is <code>-n</code> roughly one nth of the idle objects will be 487 * tested per run. 488 * 489 * @param numTestsPerEvictionRun 490 * max number of objects to examine during each evictor run 491 * 492 * @see #getNumTestsPerEvictionRun 493 * @see #setTimeBetweenEvictionRunsMillis 494 */ 495 public final void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { 496 this.numTestsPerEvictionRun = numTestsPerEvictionRun; 497 } 498 499 /** 500 * Returns the minimum amount of time an object may sit idle in the pool 501 * before it is eligible for eviction by the idle object evictor (if any - 502 * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive, 503 * no objects will be evicted from the pool due to idle time alone. 504 * 505 * @return minimum amount of time an object may sit idle in the pool before 506 * it is eligible for eviction 507 * 508 * @see #setMinEvictableIdleTimeMillis 509 * @see #setTimeBetweenEvictionRunsMillis 510 */ 511 public final long getMinEvictableIdleTimeMillis() { 512 return minEvictableIdleTimeMillis; 513 } 514 515 /** 516 * Sets the minimum amount of time an object may sit idle in the pool 517 * before it is eligible for eviction by the idle object evictor (if any - 518 * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive, 519 * no objects will be evicted from the pool due to idle time alone. 520 * 521 * @param minEvictableIdleTimeMillis 522 * minimum amount of time an object may sit idle in the pool 523 * before it is eligible for eviction 524 * 525 * @see #getMinEvictableIdleTimeMillis 526 * @see #setTimeBetweenEvictionRunsMillis 527 */ 528 public final void setMinEvictableIdleTimeMillis( 529 long minEvictableIdleTimeMillis) { 530 this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 531 } 532 533 /** 534 * Returns the minimum amount of time an object may sit idle in the pool 535 * before it is eligible for eviction by the idle object evictor (if any - 536 * see {@link #setTimeBetweenEvictionRunsMillis(long)}), 537 * with the extra condition that at least <code>minIdle</code> object 538 * instances remain in the pool. This setting is overridden by 539 * {@link #getMinEvictableIdleTimeMillis} (that is, if 540 * {@link #getMinEvictableIdleTimeMillis} is positive, then 541 * {@link #getSoftMinEvictableIdleTimeMillis} is ignored). 542 * 543 * @return minimum amount of time an object may sit idle in the pool before 544 * it is eligible for eviction if minIdle instances are available 545 * 546 * @see #setSoftMinEvictableIdleTimeMillis 547 */ 548 public final long getSoftMinEvictableIdleTimeMillis() { 549 return softMinEvictableIdleTimeMillis; 550 } 551 552 /** 553 * Sets the minimum amount of time an object may sit idle in the pool 554 * before it is eligible for eviction by the idle object evictor (if any - 555 * see {@link #setTimeBetweenEvictionRunsMillis(long)}), 556 * with the extra condition that at least <code>minIdle</code> object 557 * instances remain in the pool. This setting is overridden by 558 * {@link #getMinEvictableIdleTimeMillis} (that is, if 559 * {@link #getMinEvictableIdleTimeMillis} is positive, then 560 * {@link #getSoftMinEvictableIdleTimeMillis} is ignored). 561 * 562 * @param softMinEvictableIdleTimeMillis 563 * minimum amount of time an object may sit idle in the pool 564 * before it is eligible for eviction if minIdle instances are 565 * available 566 * 567 * @see #getSoftMinEvictableIdleTimeMillis 568 */ 569 public final void setSoftMinEvictableIdleTimeMillis( 570 long softMinEvictableIdleTimeMillis) { 571 this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; 572 } 573 574 /** 575 * Returns the name of the {@link EvictionPolicy} implementation that is 576 * used by this pool. 577 * 578 * @return The fully qualified class name of the {@link EvictionPolicy} 579 * 580 * @see #setEvictionPolicyClassName(String) 581 */ 582 public final String getEvictionPolicyClassName() { 583 return evictionPolicy.getClass().getName(); 584 } 585 586 /** 587 * Sets the name of the {@link EvictionPolicy} implementation that is 588 * used by this pool. 589 * 590 * @param evictionPolicyClassName the fully qualified class name of the 591 * new eviction policy 592 * 593 * @see #getEvictionPolicyClassName() 594 */ 595 public final void setEvictionPolicyClassName( 596 String evictionPolicyClassName) { 597 try { 598 Class<?> clazz = Class.forName(evictionPolicyClassName, true, 599 Thread.currentThread().getContextClassLoader()); 600 Object policy = clazz.newInstance(); 601 if (policy instanceof EvictionPolicy<?>) { 602 @SuppressWarnings("unchecked") // safe, because we just checked the class 603 EvictionPolicy<T> evicPolicy = (EvictionPolicy<T>) policy; 604 this.evictionPolicy = evicPolicy; 605 } 606 } catch (ClassNotFoundException e) { 607 throw new IllegalArgumentException( 608 "Unable to create EvictionPolicy instance of type " + 609 evictionPolicyClassName, e); 610 } catch (InstantiationException e) { 611 throw new IllegalArgumentException( 612 "Unable to create EvictionPolicy instance of type " + 613 evictionPolicyClassName, e); 614 } catch (IllegalAccessException e) { 615 throw new IllegalArgumentException( 616 "Unable to create EvictionPolicy instance of type " + 617 evictionPolicyClassName, e); 618 } 619 } 620 621 622 /** 623 * Closes the pool, destroys the remaining idle objects and, if registered 624 * in JMX, deregisters it. 625 */ 626 public abstract void close(); 627 628 /** 629 * Has this pool instance been closed. 630 * @return <code>true</code> when this pool has been closed. 631 */ 632 public final boolean isClosed() { 633 return closed; 634 } 635 636 /** 637 * <p>Perform <code>numTests</code> idle object eviction tests, evicting 638 * examined objects that meet the criteria for eviction. If 639 * <code>testWhileIdle</code> is true, examined objects are validated 640 * when visited (and removed if invalid); otherwise only objects that 641 * have been idle for more than <code>minEvicableIdleTimeMillis</code> 642 * are removed.</p> 643 * 644 * @throws Exception when there is a problem evicting idle objects. 645 */ 646 public abstract void evict() throws Exception; 647 648 /** 649 * Returns the {@link EvictionPolicy} defined for this pool. 650 * @return the eviction policy 651 */ 652 final EvictionPolicy<T> getEvictionPolicy() { 653 return evictionPolicy; 654 } 655 656 /** 657 * Verifies that the pool is open. 658 * @throws IllegalStateException if the pool is closed. 659 */ 660 final void assertOpen() throws IllegalStateException { 661 if (isClosed()) { 662 throw new IllegalStateException("Pool not open"); 663 } 664 } 665 666 /** 667 * <p>Starts the evictor with the given delay. If there is an evictor 668 * running when this method is called, it is stopped and replaced with a 669 * new evictor with the specified delay.</p> 670 * 671 * <p>This method needs to be final, since it is called from a constructor. 672 * See POOL-195.</p> 673 * 674 * @param delay time in milliseconds before start and between eviction runs 675 */ 676 final void startEvictor(long delay) { 677 synchronized (evictionLock) { 678 if (null != evictor) { 679 EvictionTimer.cancel(evictor); 680 evictor = null; 681 evictionIterator = null; 682 } 683 if (delay > 0) { 684 evictor = new Evictor(); 685 EvictionTimer.schedule(evictor, delay, delay); 686 } 687 } 688 } 689 690 /** 691 * Tries to ensure that the configured minimum number of idle instances are 692 * available in the pool. 693 * @throws Exception if an error occurs creating idle instances 694 */ 695 abstract void ensureMinIdle() throws Exception; 696 697 698 // Monitoring (primarily JMX) related methods 699 700 /** 701 * Provides the name under which the pool has been registered with the 702 * platform MBean server or <code>null</code> if the pool has not been 703 * registered. 704 * @return the JMX name 705 */ 706 public final ObjectName getJmxName() { 707 return oname; 708 } 709 710 /** 711 * Provides the stack trace for the call that created this pool. JMX 712 * registration may trigger a memory leak so it is important that pools are 713 * deregistered when no longer used by calling the {@link #close()} method. 714 * This method is provided to assist with identifying code that creates but 715 * does not close it thereby creating a memory leak. 716 * @return pool creation stack trace 717 */ 718 public final String getCreationStackTrace() { 719 return creationStackTrace; 720 } 721 722 /** 723 * The total number of objects successfully borrowed from this pool over the 724 * lifetime of the pool. 725 * @return the borrowed object count 726 */ 727 public final long getBorrowedCount() { 728 return borrowedCount.get(); 729 } 730 731 /** 732 * The total number of objects returned to this pool over the lifetime of 733 * the pool. This excludes attempts to return the same object multiple 734 * times. 735 * @return the returned object count 736 */ 737 public final long getReturnedCount() { 738 return returnedCount.get(); 739 } 740 741 /** 742 * The total number of objects created for this pool over the lifetime of 743 * the pool. 744 * @return the created object count 745 */ 746 public final long getCreatedCount() { 747 return createdCount.get(); 748 } 749 750 /** 751 * The total number of objects destroyed by this pool over the lifetime of 752 * the pool. 753 * @return the destroyed object count 754 */ 755 public final long getDestroyedCount() { 756 return destroyedCount.get(); 757 } 758 759 /** 760 * The total number of objects destroyed by the evictor associated with this 761 * pool over the lifetime of the pool. 762 * @return the evictor destroyed object count 763 */ 764 public final long getDestroyedByEvictorCount() { 765 return destroyedByEvictorCount.get(); 766 } 767 768 /** 769 * The total number of objects destroyed by this pool as a result of failing 770 * validation during <code>borrowObject()</code> over the lifetime of the 771 * pool. 772 * @return validation destroyed object count 773 */ 774 public final long getDestroyedByBorrowValidationCount() { 775 return destroyedByBorrowValidationCount.get(); 776 } 777 778 /** 779 * The mean time objects are active for based on the last {@link 780 * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool. 781 * @return mean time an object has been checked out from the pool among 782 * recently returned objects 783 */ 784 public final long getMeanActiveTimeMillis() { 785 return activeTimes.getMean(); 786 } 787 788 /** 789 * The mean time objects are idle for based on the last {@link 790 * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool. 791 * @return mean time an object has been idle in the pool among recently 792 * borrowed objects 793 */ 794 public final long getMeanIdleTimeMillis() { 795 return idleTimes.getMean(); 796 } 797 798 /** 799 * The mean time threads wait to borrow an object based on the last {@link 800 * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool. 801 * @return mean time in milliseconds that a recently served thread has had 802 * to wait to borrow an object from the pool 803 */ 804 public final long getMeanBorrowWaitTimeMillis() { 805 return waitTimes.getMean(); 806 } 807 808 /** 809 * The maximum time a thread has waited to borrow objects from the pool. 810 * @return maximum wait time in milliseconds since the pool was created 811 */ 812 public final long getMaxBorrowWaitTimeMillis() { 813 return maxBorrowWaitTimeMillis.get(); 814 } 815 816 /** 817 * The number of instances currently idle in this pool. 818 * @return count of instances available for checkout from the pool 819 */ 820 public abstract int getNumIdle(); 821 822 /** 823 * The listener used (if any) to receive notifications of exceptions 824 * unavoidably swallowed by the pool. 825 * 826 * @return The listener or <code>null</code> for no listener 827 */ 828 public final SwallowedExceptionListener getSwallowedExceptionListener() { 829 return swallowedExceptionListener; 830 } 831 832 /** 833 * The listener used (if any) to receive notifications of exceptions 834 * unavoidably swallowed by the pool. 835 * 836 * @param swallowedExceptionListener The listener or <code>null</code> 837 * for no listener 838 */ 839 public final void setSwallowedExceptionListener( 840 SwallowedExceptionListener swallowedExceptionListener) { 841 this.swallowedExceptionListener = swallowedExceptionListener; 842 } 843 844 /** 845 * Swallows an exception and notifies the configured listener for swallowed 846 * exceptions queue. 847 * 848 * @param e exception to be swallowed 849 */ 850 final void swallowException(Exception e) { 851 SwallowedExceptionListener listener = getSwallowedExceptionListener(); 852 853 if (listener == null) { 854 return; 855 } 856 857 try { 858 listener.onSwallowException(e); 859 } catch (OutOfMemoryError oome) { 860 throw oome; 861 } catch (VirtualMachineError vme) { 862 throw vme; 863 } catch (Throwable t) { 864 // Ignore. Enjoy the irony. 865 } 866 } 867 868 /** 869 * Updates statistics after an object is borrowed from the pool. 870 * @param p object borrowed from the pool 871 * @param waitTime time (in milliseconds) that the borrowing thread had to wait 872 */ 873 final void updateStatsBorrow(PooledObject<T> p, long waitTime) { 874 borrowedCount.incrementAndGet(); 875 idleTimes.add(p.getIdleTimeMillis()); 876 waitTimes.add(waitTime); 877 878 // lock-free optimistic-locking maximum 879 long currentMax; 880 do { 881 currentMax = maxBorrowWaitTimeMillis.get(); 882 if (currentMax >= waitTime) { 883 break; 884 } 885 } while (!maxBorrowWaitTimeMillis.compareAndSet(currentMax, waitTime)); 886 } 887 888 /** 889 * Updates statistics after an object is returned to the pool. 890 * @param activeTime the amount of time (in milliseconds) that the returning 891 * object was checked out 892 */ 893 final void updateStatsReturn(long activeTime) { 894 returnedCount.incrementAndGet(); 895 activeTimes.add(activeTime); 896 } 897 898 /** 899 * Unregisters this pool's MBean. 900 */ 901 final void jmxUnregister() { 902 if (oname != null) { 903 try { 904 ManagementFactory.getPlatformMBeanServer().unregisterMBean( 905 oname); 906 } catch (MBeanRegistrationException e) { 907 swallowException(e); 908 } catch (InstanceNotFoundException e) { 909 swallowException(e); 910 } 911 } 912 } 913 914 /** 915 * Registers the pool with the platform MBean server. 916 * The registered name will be 917 * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least 918 * integer greater than or equal to 1 such that the name is not already 919 * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException 920 * returning null. 921 * 922 * @param config Pool configuration 923 * @param jmxNameBase default base JMX name for this pool 924 * @param jmxNamePrefix name prefix 925 * @return registered ObjectName, null if registration fails 926 */ 927 private ObjectName jmxRegister(BaseObjectPoolConfig config, 928 String jmxNameBase, String jmxNamePrefix) { 929 ObjectName objectName = null; 930 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 931 int i = 1; 932 boolean registered = false; 933 String base = config.getJmxNameBase(); 934 if (base == null) { 935 base = jmxNameBase; 936 } 937 while (!registered) { 938 try { 939 ObjectName objName; 940 // Skip the numeric suffix for the first pool in case there is 941 // only one so the names are cleaner. 942 if (i == 1) { 943 objName = new ObjectName(base + jmxNamePrefix); 944 } else { 945 objName = new ObjectName(base + jmxNamePrefix + i); 946 } 947 mbs.registerMBean(this, objName); 948 objectName = objName; 949 registered = true; 950 } catch (MalformedObjectNameException e) { 951 if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals( 952 jmxNamePrefix) && jmxNameBase.equals(base)) { 953 // Shouldn't happen. Skip registration if it does. 954 registered = true; 955 } else { 956 // Must be an invalid name. Use the defaults instead. 957 jmxNamePrefix = 958 BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX; 959 base = jmxNameBase; 960 } 961 } catch (InstanceAlreadyExistsException e) { 962 // Increment the index and try again 963 i++; 964 } catch (MBeanRegistrationException e) { 965 // Shouldn't happen. Skip registration if it does. 966 registered = true; 967 } catch (NotCompliantMBeanException e) { 968 // Shouldn't happen. Skip registration if it does. 969 registered = true; 970 } 971 } 972 return objectName; 973 } 974 975 /** 976 * Gets the stack trace of an exception as a string. 977 * @param e exception to trace 978 * @return exception stack trace as a string 979 */ 980 private String getStackTrace(Exception e) { 981 // Need the exception in string form to prevent the retention of 982 // references to classes in the stack trace that could trigger a memory 983 // leak in a container environment. 984 Writer w = new StringWriter(); 985 PrintWriter pw = new PrintWriter(w); 986 e.printStackTrace(pw); 987 return w.toString(); 988 } 989 990 // Inner classes 991 992 /** 993 * The idle object evictor {@link TimerTask}. 994 * 995 * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis 996 */ 997 class Evictor extends TimerTask { 998 /** 999 * Run pool maintenance. Evict objects qualifying for eviction and then 1000 * ensure that the minimum number of idle instances are available. 1001 * Since the Timer that invokes Evictors is shared for all Pools but 1002 * pools may exist in different class loaders, the Evictor ensures that 1003 * any actions taken are under the class loader of the factory 1004 * associated with the pool. 1005 */ 1006 @Override 1007 public void run() { 1008 ClassLoader savedClassLoader = 1009 Thread.currentThread().getContextClassLoader(); 1010 try { 1011 if (factoryClassLoader != null) { 1012 // Set the class loader for the factory 1013 ClassLoader cl = factoryClassLoader.get(); 1014 if (cl == null) { 1015 // The pool has been dereferenced and the class loader 1016 // GC'd. Cancel this timer so the pool can be GC'd as 1017 // well. 1018 cancel(); 1019 return; 1020 } 1021 Thread.currentThread().setContextClassLoader(cl); 1022 } 1023 1024 // Evict from the pool 1025 try { 1026 evict(); 1027 } catch(Exception e) { 1028 swallowException(e); 1029 } catch(OutOfMemoryError oome) { 1030 // Log problem but give evictor thread a chance to continue 1031 // in case error is recoverable 1032 oome.printStackTrace(System.err); 1033 } 1034 // Re-create idle instances. 1035 try { 1036 ensureMinIdle(); 1037 } catch (Exception e) { 1038 swallowException(e); 1039 } 1040 } finally { 1041 // Restore the previous CCL 1042 Thread.currentThread().setContextClassLoader(savedClassLoader); 1043 } 1044 } 1045 } 1046 1047 /** 1048 * Maintains a cache of values for a single metric and reports 1049 * statistics on the cached values. 1050 */ 1051 private class StatsStore { 1052 1053 private final AtomicLong values[]; 1054 private final int size; 1055 private int index; 1056 1057 /** 1058 * Create a StatsStore with the given cache size. 1059 * 1060 * @param size number of values to maintain in the cache. 1061 */ 1062 public StatsStore(int size) { 1063 this.size = size; 1064 values = new AtomicLong[size]; 1065 for (int i = 0; i < size; i++) { 1066 values[i] = new AtomicLong(-1); 1067 } 1068 } 1069 1070 /** 1071 * Adds a value to the cache. If the cache is full, one of the 1072 * existing values is replaced by the new value. 1073 * 1074 * @param value new value to add to the cache. 1075 */ 1076 public synchronized void add(long value) { 1077 values[index].set(value); 1078 index++; 1079 if (index == size) { 1080 index = 0; 1081 } 1082 } 1083 1084 /** 1085 * Returns the mean of the cached values. 1086 * 1087 * @return the mean of the cache, truncated to long 1088 */ 1089 public long getMean() { 1090 double result = 0; 1091 int counter = 0; 1092 for (int i = 0; i < size; i++) { 1093 long value = values[i].get(); 1094 if (value != -1) { 1095 counter++; 1096 result = result * ((counter - 1) / (double) counter) + 1097 value/(double) counter; 1098 } 1099 } 1100 return (long) result; 1101 } 1102 } 1103}