BaseGenericObjectPool.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.pool2.impl;

  18. import java.io.PrintWriter;
  19. import java.io.StringWriter;
  20. import java.io.Writer;
  21. import java.lang.management.ManagementFactory;
  22. import java.lang.ref.WeakReference;
  23. import java.lang.reflect.InvocationTargetException;
  24. import java.time.Duration;
  25. import java.time.Instant;
  26. import java.util.ArrayList;
  27. import java.util.Arrays;
  28. import java.util.Deque;
  29. import java.util.Iterator;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.TimerTask;
  33. import java.util.concurrent.ScheduledFuture;
  34. import java.util.concurrent.atomic.AtomicLong;
  35. import java.util.concurrent.atomic.AtomicReference;
  36. import java.util.stream.Collectors;

  37. import javax.management.InstanceAlreadyExistsException;
  38. import javax.management.InstanceNotFoundException;
  39. import javax.management.MBeanRegistrationException;
  40. import javax.management.MBeanServer;
  41. import javax.management.MalformedObjectNameException;
  42. import javax.management.NotCompliantMBeanException;
  43. import javax.management.ObjectName;

  44. import org.apache.commons.pool2.BaseObject;
  45. import org.apache.commons.pool2.PooledObject;
  46. import org.apache.commons.pool2.PooledObjectState;
  47. import org.apache.commons.pool2.SwallowedExceptionListener;

  48. /**
  49.  * Base class that provides common functionality for {@link GenericObjectPool}
  50.  * and {@link GenericKeyedObjectPool}. The primary reason this class exists is
  51.  * reduce code duplication between the two pool implementations.
  52.  * <p>
  53.  * Concrete implementations of this class are expected to be thread-safe.
  54.  * </p>
  55.  *
  56.  * @param <T> Type of element pooled in this pool.
  57.  * @since 2.0
  58.  */
  59. public abstract class BaseGenericObjectPool<T> extends BaseObject implements AutoCloseable {

  60.     /**
  61.      * The idle object eviction iterator. Holds a reference to the idle objects.
  62.      */
  63.     final class EvictionIterator implements Iterator<PooledObject<T>> {

  64.         private final Deque<PooledObject<T>> idleObjects;
  65.         private final Iterator<PooledObject<T>> idleObjectIterator;

  66.         /**
  67.          * Constructs an EvictionIterator for the provided idle instance deque.
  68.          * @param idleObjects underlying deque.
  69.          */
  70.         EvictionIterator(final Deque<PooledObject<T>> idleObjects) {
  71.             this.idleObjects = idleObjects;

  72.             if (getLifo()) {
  73.                 idleObjectIterator = idleObjects.descendingIterator();
  74.             } else {
  75.                 idleObjectIterator = idleObjects.iterator();
  76.             }
  77.         }

  78.         /**
  79.          * Gets the idle object deque referenced by this iterator.
  80.          * @return the idle object deque
  81.          */
  82.         public Deque<PooledObject<T>> getIdleObjects() {
  83.             return idleObjects;
  84.         }

  85.         /** {@inheritDoc} */
  86.         @Override
  87.         public boolean hasNext() {
  88.             return idleObjectIterator.hasNext();
  89.         }

  90.         /** {@inheritDoc} */
  91.         @Override
  92.         public PooledObject<T> next() {
  93.             return idleObjectIterator.next();
  94.         }

  95.         /** {@inheritDoc} */
  96.         @Override
  97.         public void remove() {
  98.             idleObjectIterator.remove();
  99.         }

  100.     }

  101.     /**
  102.      * The idle object evictor {@link TimerTask}.
  103.      *
  104.      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
  105.      */
  106.     final class Evictor implements Runnable {

  107.         private ScheduledFuture<?> scheduledFuture;

  108.         /**
  109.          * Cancels the scheduled future.
  110.          */
  111.         void cancel() {
  112.             scheduledFuture.cancel(false);
  113.         }

  114.         BaseGenericObjectPool<T> owner() {
  115.             return BaseGenericObjectPool.this;
  116.         }

  117.         /**
  118.          * Run pool maintenance.  Evict objects qualifying for eviction and then
  119.          * ensure that the minimum number of idle instances are available.
  120.          * Since the Timer that invokes Evictors is shared for all Pools but
  121.          * pools may exist in different class loaders, the Evictor ensures that
  122.          * any actions taken are under the class loader of the factory
  123.          * associated with the pool.
  124.          */
  125.         @Override
  126.         public void run() {
  127.             final ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
  128.             try {
  129.                 if (factoryClassLoader != null) {
  130.                     // Set the class loader for the factory
  131.                     final ClassLoader cl = factoryClassLoader.get();
  132.                     if (cl == null) {
  133.                         // The pool has been dereferenced and the class loader
  134.                         // GC'd. Cancel this timer so the pool can be GC'd as
  135.                         // well.
  136.                         cancel();
  137.                         return;
  138.                     }
  139.                     Thread.currentThread().setContextClassLoader(cl);
  140.                 }

  141.                 // Evict from the pool
  142.                 try {
  143.                     evict();
  144.                 } catch (final Exception e) {
  145.                     swallowException(e);
  146.                 } catch (final OutOfMemoryError oome) {
  147.                     // Log problem but give evictor thread a chance to continue
  148.                     // in case error is recoverable
  149.                     oome.printStackTrace(System.err);
  150.                 }
  151.                 // Re-create idle instances.
  152.                 try {
  153.                     ensureMinIdle();
  154.                 } catch (final Exception e) {
  155.                     swallowException(e);
  156.                 }
  157.             } finally {
  158.                 // Restore the previous CCL
  159.                 Thread.currentThread().setContextClassLoader(savedClassLoader);
  160.             }
  161.         }

  162.         /**
  163.          * Sets the scheduled future.
  164.          *
  165.          * @param scheduledFuture the scheduled future.
  166.          */
  167.         void setScheduledFuture(final ScheduledFuture<?> scheduledFuture) {
  168.             this.scheduledFuture = scheduledFuture;
  169.         }

  170.         @Override
  171.         public String toString() {
  172.             return getClass().getName() + " [scheduledFuture=" + scheduledFuture + "]";
  173.         }

  174.     }

  175.     /**
  176.      * Wrapper for objects under management by the pool.
  177.      *
  178.      * GenericObjectPool and GenericKeyedObjectPool maintain references to all
  179.      * objects under management using maps keyed on the objects. This wrapper
  180.      * class ensures that objects can work as hash keys.
  181.      *
  182.      * @param <T> type of objects in the pool
  183.      */
  184.     static class IdentityWrapper<T> {
  185.         /** Wrapped object */
  186.         private final T instance;

  187.         /**
  188.          * Constructs a wrapper for an instance.
  189.          *
  190.          * @param instance object to wrap
  191.          */
  192.         public IdentityWrapper(final T instance) {
  193.             this.instance = instance;
  194.         }

  195.         @Override
  196.         @SuppressWarnings("rawtypes")
  197.         public boolean equals(final Object other) {
  198.             return other instanceof IdentityWrapper && ((IdentityWrapper) other).instance == instance;
  199.         }

  200.         /**
  201.          * @return the wrapped object
  202.          */
  203.         public T getObject() {
  204.             return instance;
  205.         }

  206.         @Override
  207.         public int hashCode() {
  208.             return System.identityHashCode(instance);
  209.         }

  210.         @Override
  211.         public String toString() {
  212.             final StringBuilder builder = new StringBuilder();
  213.             builder.append("IdentityWrapper [instance=");
  214.             builder.append(instance);
  215.             builder.append("]");
  216.             return builder.toString();
  217.         }
  218.     }

  219.     /**
  220.      * Maintains a cache of values for a single metric and reports
  221.      * statistics on the cached values.
  222.      */
  223.     private static final class StatsStore {

  224.         private static final int NONE = -1;
  225.         private final AtomicLong[] values;
  226.         private final int size;
  227.         private int index;

  228.         /**
  229.          * Constructs a new instance with the given cache size.
  230.          *
  231.          * @param size number of values to maintain in the cache.
  232.          */
  233.         StatsStore(final int size) {
  234.             this.size = size;
  235.             this.values = new AtomicLong[size];
  236.             Arrays.setAll(values, i -> new AtomicLong(NONE));
  237.         }

  238.         void add(final Duration value) {
  239.             add(value.toMillis());
  240.         }

  241.         /**
  242.          * Adds a value to the cache.  If the cache is full, one of the
  243.          * existing values is replaced by the new value.
  244.          *
  245.          * @param value new value to add to the cache.
  246.          */
  247.         synchronized void add(final long value) {
  248.             values[index].set(value);
  249.             index++;
  250.             if (index == size) {
  251.                 index = 0;
  252.             }
  253.         }

  254.         /**
  255.          * Gets the mean of the cached values.
  256.          *
  257.          * @return the mean of the cache, truncated to long
  258.          */
  259.         public long getMean() {
  260.             double result = 0;
  261.             int counter = 0;
  262.             for (int i = 0; i < size; i++) {
  263.                 final long value = values[i].get();
  264.                 if (value != NONE) {
  265.                     counter++;
  266.                     result = result * ((counter - 1) / (double) counter) + value / (double) counter;
  267.                 }
  268.             }
  269.             return (long) result;
  270.         }

  271.         /**
  272.          * Gets the mean Duration of the cached values.
  273.          *
  274.          * @return the mean Duration of the cache, truncated to long milliseconds of a Duration.
  275.          */
  276.         Duration getMeanDuration() {
  277.             return Duration.ofMillis(getMean());
  278.         }

  279.         /**
  280.          * Gets the current values as a List.
  281.          *
  282.          * @return the current values as a List.
  283.          */
  284.         synchronized List<AtomicLong> getValues() {
  285.             return Arrays.stream(values, 0, index).collect(Collectors.toList());
  286.         }

  287.         @Override
  288.         public String toString() {
  289.             final StringBuilder builder = new StringBuilder();
  290.             builder.append("StatsStore [");
  291.             // Only append what's been filled in.
  292.             builder.append(getValues());
  293.             builder.append("], size=");
  294.             builder.append(size);
  295.             builder.append(", index=");
  296.             builder.append(index);
  297.             builder.append("]");
  298.             return builder.toString();
  299.         }

  300.     }

  301.     // Constants
  302.     /**
  303.      * The size of the caches used to store historical data for some attributes
  304.      * so that rolling means may be calculated.
  305.      */
  306.     public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100;
  307.     private static final String EVICTION_POLICY_TYPE_NAME = EvictionPolicy.class.getName();
  308.     private static final Duration DEFAULT_REMOVE_ABANDONED_TIMEOUT = Duration.ofSeconds(Integer.MAX_VALUE);
  309.     // Configuration attributes
  310.     private volatile int maxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
  311.     private volatile boolean blockWhenExhausted = BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
  312.     private volatile Duration maxWaitDuration = BaseObjectPoolConfig.DEFAULT_MAX_WAIT;
  313.     private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
  314.     private final boolean fairness;
  315.     private volatile boolean testOnCreate = BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
  316.     private volatile boolean testOnBorrow = BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
  317.     private volatile boolean testOnReturn = BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
  318.     private volatile boolean testWhileIdle = BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
  319.     private volatile Duration durationBetweenEvictionRuns = BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS;
  320.     private volatile int numTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;

  321.     private volatile Duration minEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION;
  322.     private volatile Duration softMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION;
  323.     private volatile EvictionPolicy<T> evictionPolicy;
  324.     private volatile Duration evictorShutdownTimeoutDuration = BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT;
  325.     // Internal (primarily state) attributes
  326.     final Object closeLock = new Object();
  327.     volatile boolean closed;

  328.     final Object evictionLock = new Object();
  329.     private Evictor evictor; // @GuardedBy("evictionLock")
  330.     EvictionIterator evictionIterator; // @GuardedBy("evictionLock")

  331.     /**
  332.      * Class loader for evictor thread to use since, in a JavaEE or similar
  333.      * environment, the context class loader for the evictor thread may not have
  334.      * visibility of the correct factory. See POOL-161. Uses a weak reference to
  335.      * avoid potential memory leaks if the Pool is discarded rather than closed.
  336.      */
  337.     private final WeakReference<ClassLoader> factoryClassLoader;
  338.     // Monitoring (primarily JMX) attributes
  339.     private final ObjectName objectName;
  340.     private final String creationStackTrace;
  341.     private final AtomicLong borrowedCount = new AtomicLong();
  342.     private final AtomicLong returnedCount = new AtomicLong();
  343.     final AtomicLong createdCount = new AtomicLong();
  344.     final AtomicLong destroyedCount = new AtomicLong();
  345.     final AtomicLong destroyedByEvictorCount = new AtomicLong();
  346.     final AtomicLong destroyedByBorrowValidationCount = new AtomicLong();

  347.     private final StatsStore activeTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
  348.     private final StatsStore idleTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
  349.     private final StatsStore waitTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);

  350.     private final AtomicReference<Duration> maxBorrowWaitDuration = new AtomicReference<>(Duration.ZERO);

  351.     private volatile SwallowedExceptionListener swallowedExceptionListener;
  352.     private volatile boolean messageStatistics;

  353.     /** Additional configuration properties for abandoned object tracking. */
  354.     protected volatile AbandonedConfig abandonedConfig;

  355.     /**
  356.      * Handles JMX registration (if required) and the initialization required for
  357.      * monitoring.
  358.      *
  359.      * @param config        Pool configuration
  360.      * @param jmxNameBase   The default base JMX name for the new pool unless
  361.      *                      overridden by the config
  362.      * @param jmxNamePrefix Prefix to be used for JMX name for the new pool
  363.      */
  364.     public BaseGenericObjectPool(final BaseObjectPoolConfig<T> config,
  365.             final String jmxNameBase, final String jmxNamePrefix) {
  366.         if (config.getJmxEnabled()) {
  367.             this.objectName = jmxRegister(config, jmxNameBase, jmxNamePrefix);
  368.         } else {
  369.             this.objectName = null;
  370.         }

  371.         // Populate the creation stack trace
  372.         this.creationStackTrace = getStackTrace(new Exception());

  373.         // save the current TCCL (if any) to be used later by the evictor Thread
  374.         final ClassLoader cl = Thread.currentThread().getContextClassLoader();
  375.         if (cl == null) {
  376.             factoryClassLoader = null;
  377.         } else {
  378.             factoryClassLoader = new WeakReference<>(cl);
  379.         }

  380.         fairness = config.getFairness();
  381.     }

  382.     /**
  383.      * Appends statistics if enabled.
  384.      * <p>
  385.      * Statistics may not accurately reflect snapshot state at the time of the exception because we do not want to lock the pool when gathering this
  386.      * information.
  387.      * </p>
  388.      *
  389.      * @param string The root string.
  390.      * @return The root string plus statistics.
  391.      */
  392.     String appendStats(final String string) {
  393.         return messageStatistics ? string + ", " + getStatsString() : string;
  394.     }

  395.     /**
  396.      * Verifies that the pool is open.
  397.      * @throws IllegalStateException if the pool is closed.
  398.      */
  399.     final void assertOpen() throws IllegalStateException {
  400.         if (isClosed()) {
  401.             throw new IllegalStateException("Pool not open");
  402.         }
  403.     }

  404.     /**
  405.      * Closes the pool, destroys the remaining idle objects and, if registered
  406.      * in JMX, deregisters it.
  407.      */
  408.     @Override
  409.     public abstract void close();

  410.     /**
  411.      * Creates a list of pooled objects to remove based on their state.
  412.      * @param abandonedConfig The abandoned configuration.
  413.      * @param allObjects PooledObject instances to consider.
  414.      * @return a list of pooled objects to remove based on their state.
  415.      */
  416.     ArrayList<PooledObject<T>> createRemoveList(final AbandonedConfig abandonedConfig, final Map<IdentityWrapper<T>, PooledObject<T>> allObjects) {
  417.         final Instant timeout = Instant.now().minus(abandonedConfig.getRemoveAbandonedTimeoutDuration());
  418.         final ArrayList<PooledObject<T>> remove = new ArrayList<>();
  419.         allObjects.values().forEach(pooledObject -> {
  420.             synchronized (pooledObject) {
  421.                 if (pooledObject.getState() == PooledObjectState.ALLOCATED &&
  422.                         pooledObject.getLastUsedInstant().compareTo(timeout) <= 0) {
  423.                     pooledObject.markAbandoned();
  424.                     remove.add(pooledObject);
  425.                 }
  426.             }
  427.         });
  428.         return remove;
  429.     }

  430.     /**
  431.      * Tries to ensure that the configured minimum number of idle instances are
  432.      * available in the pool.
  433.      * @throws Exception if an error occurs creating idle instances
  434.      */
  435.     abstract void ensureMinIdle() throws Exception;

  436.     /**
  437.      * Perform {@code numTests} idle object eviction tests, evicting
  438.      * examined objects that meet the criteria for eviction. If
  439.      * {@code testWhileIdle} is true, examined objects are validated
  440.      * when visited (and removed if invalid); otherwise only objects that
  441.      * have been idle for more than {@code minEvicableIdleTimeMillis}
  442.      * are removed.
  443.      *
  444.      * @throws Exception when there is a problem evicting idle objects.
  445.      */
  446.     public abstract void evict() throws Exception;

  447.     /**
  448.      * Gets whether to block when the {@code borrowObject()} method is
  449.      * invoked when the pool is exhausted (the maximum number of "active"
  450.      * objects has been reached).
  451.      *
  452.      * @return {@code true} if {@code borrowObject()} should block
  453.      *         when the pool is exhausted
  454.      *
  455.      * @see #setBlockWhenExhausted
  456.      */
  457.     public final boolean getBlockWhenExhausted() {
  458.         return blockWhenExhausted;
  459.     }

  460.     /**
  461.      * Gets the total number of objects successfully borrowed from this pool over the
  462.      * lifetime of the pool.
  463.      * @return the borrowed object count
  464.      */
  465.     public final long getBorrowedCount() {
  466.         return borrowedCount.get();
  467.     }

  468.     /**
  469.      * Gets the total number of objects created for this pool over the lifetime of
  470.      * the pool.
  471.      * @return the created object count
  472.      */
  473.     public final long getCreatedCount() {
  474.         return createdCount.get();
  475.     }

  476.     /**
  477.      * Gets the stack trace for the call that created this pool. JMX
  478.      * registration may trigger a memory leak so it is important that pools are
  479.      * deregistered when no longer used by calling the {@link #close()} method.
  480.      * This method is provided to assist with identifying code that creates but
  481.      * does not close it thereby creating a memory leak.
  482.      * @return pool creation stack trace
  483.      */
  484.     public final String getCreationStackTrace() {
  485.         return creationStackTrace;
  486.     }

  487.     /**
  488.      * Gets the total number of objects destroyed by this pool as a result of failing
  489.      * validation during {@code borrowObject()} over the lifetime of the
  490.      * pool.
  491.      * @return validation destroyed object count
  492.      */
  493.     public final long getDestroyedByBorrowValidationCount() {
  494.         return destroyedByBorrowValidationCount.get();
  495.     }

  496.     /**
  497.      * Gets the total number of objects destroyed by the evictor associated with this
  498.      * pool over the lifetime of the pool.
  499.      * @return the evictor destroyed object count
  500.      */
  501.     public final long getDestroyedByEvictorCount() {
  502.         return destroyedByEvictorCount.get();
  503.     }

  504.     /**
  505.      * Gets the total number of objects destroyed by this pool over the lifetime of
  506.      * the pool.
  507.      * @return the destroyed object count
  508.      */
  509.     public final long getDestroyedCount() {
  510.         return destroyedCount.get();
  511.     }

  512.     /**
  513.      * Gets the duration to sleep between runs of the idle
  514.      * object evictor thread. When non-positive, no idle object evictor thread
  515.      * will be run.
  516.      *
  517.      * @return number of milliseconds to sleep between evictor runs
  518.      * @see #setTimeBetweenEvictionRuns
  519.      * @since 2.11.0
  520.      */
  521.     public final Duration getDurationBetweenEvictionRuns() {
  522.         return durationBetweenEvictionRuns;
  523.     }

  524.     /**
  525.      * Gets the {@link EvictionPolicy} defined for this pool.
  526.      *
  527.      * @return the eviction policy
  528.      * @since 2.4
  529.      * @since 2.6.0 Changed access from protected to public.
  530.      */
  531.     public EvictionPolicy<T> getEvictionPolicy() {
  532.         return evictionPolicy;
  533.     }

  534.     /**
  535.      * Gets the name of the {@link EvictionPolicy} implementation that is
  536.      * used by this pool.
  537.      *
  538.      * @return  The fully qualified class name of the {@link EvictionPolicy}
  539.      * @see #setEvictionPolicyClassName(String)
  540.      */
  541.     public final String getEvictionPolicyClassName() {
  542.         return evictionPolicy.getClass().getName();
  543.     }

  544.     /**
  545.      * Gets the timeout that will be used when waiting for the Evictor to
  546.      * shutdown if this pool is closed and it is the only pool still using the
  547.      * the value for the Evictor.
  548.      *
  549.      * @return  The timeout that will be used while waiting for
  550.      *          the Evictor to shut down.
  551.      * @since 2.10.0
  552.      * @deprecated Use {@link #getEvictorShutdownTimeoutDuration()}.
  553.      */
  554.     @Deprecated
  555.     public final Duration getEvictorShutdownTimeout() {
  556.         return evictorShutdownTimeoutDuration;
  557.     }

  558.     /**
  559.      * Gets the timeout that will be used when waiting for the Evictor to
  560.      * shutdown if this pool is closed and it is the only pool still using the
  561.      * the value for the Evictor.
  562.      *
  563.      * @return  The timeout that will be used while waiting for
  564.      *          the Evictor to shut down.
  565.      * @since 2.11.0
  566.      */
  567.     public final Duration getEvictorShutdownTimeoutDuration() {
  568.         return evictorShutdownTimeoutDuration;
  569.     }

  570.     /**
  571.      * Gets the timeout that will be used when waiting for the Evictor to
  572.      * shutdown if this pool is closed and it is the only pool still using the
  573.      * the value for the Evictor.
  574.      *
  575.      * @return  The timeout in milliseconds that will be used while waiting for
  576.      *          the Evictor to shut down.
  577.      * @deprecated Use {@link #getEvictorShutdownTimeoutDuration()}.
  578.      */
  579.     @Deprecated
  580.     public final long getEvictorShutdownTimeoutMillis() {
  581.         return evictorShutdownTimeoutDuration.toMillis();
  582.     }

  583.     /**
  584.      * Gets whether or not the pool serves threads waiting to borrow objects fairly.
  585.      * True means that waiting threads are served as if waiting in a FIFO queue.
  586.      *
  587.      * @return {@code true} if waiting threads are to be served
  588.      *             by the pool in arrival order
  589.      */
  590.     public final boolean getFairness() {
  591.         return fairness;
  592.     }

  593.     /**
  594.      * Gets the name under which the pool has been registered with the
  595.      * platform MBean server or {@code null} if the pool has not been
  596.      * registered.
  597.      * @return the JMX name
  598.      */
  599.     public final ObjectName getJmxName() {
  600.         return objectName;
  601.     }

  602.     /**
  603.      * Gets whether the pool has LIFO (last in, first out) behavior with
  604.      * respect to idle objects - always returning the most recently used object
  605.      * from the pool, or as a FIFO (first in, first out) queue, where the pool
  606.      * always returns the oldest object in the idle object pool.
  607.      *
  608.      * @return {@code true} if the pool is configured with LIFO behavior
  609.      *         or {@code false} if the pool is configured with FIFO
  610.      *         behavior
  611.      *
  612.      * @see #setLifo
  613.      */
  614.     public final boolean getLifo() {
  615.         return lifo;
  616.     }

  617.     /**
  618.      * Gets whether this pool identifies and logs any abandoned objects.
  619.      *
  620.      * @return {@code true} if abandoned object removal is configured for this
  621.      *         pool and removal events are to be logged otherwise {@code false}
  622.      *
  623.      * @see AbandonedConfig#getLogAbandoned()
  624.      * @since 2.11.0
  625.      */
  626.     public boolean getLogAbandoned() {
  627.         final AbandonedConfig ac = this.abandonedConfig;
  628.         return ac != null && ac.getLogAbandoned();
  629.     }

  630.     /**
  631.      * Gets the maximum time a thread has waited to borrow objects from the pool.
  632.      *
  633.      * @return maximum wait time in milliseconds since the pool was created
  634.      * @since 2.12.0
  635.      */
  636.     public final Duration getMaxBorrowWaitDuration() {
  637.         return maxBorrowWaitDuration.get();
  638.     }

  639.     /**
  640.      * Gets the maximum time a thread has waited to borrow objects from the pool.
  641.      *
  642.      * @return maximum wait time in milliseconds since the pool was created
  643.      * @deprecated Use {@link #getMaxBorrowWaitDuration()}.
  644.      */
  645.     @Deprecated
  646.     public final long getMaxBorrowWaitTimeMillis() {
  647.         return maxBorrowWaitDuration.get().toMillis();
  648.     }

  649.     /**
  650.      * Gets the maximum number of objects that can be allocated by the pool
  651.      * (checked out to clients, or idle awaiting checkout) at a given time. When
  652.      * negative, there is no limit to the number of objects that can be
  653.      * managed by the pool at one time.
  654.      *
  655.      * @return the cap on the total number of object instances managed by the
  656.      *         pool.
  657.      * @see #setMaxTotal
  658.      */
  659.     public final int getMaxTotal() {
  660.         return maxTotal;
  661.     }

  662.     /**
  663.      * Gets the maximum duration the
  664.      * {@code borrowObject()} method should block before throwing an
  665.      * exception when the pool is exhausted and
  666.      * {@link #getBlockWhenExhausted} is true. When less than 0, the
  667.      * {@code borrowObject()} method may block indefinitely.
  668.      *
  669.      * @return the maximum number of milliseconds {@code borrowObject()}
  670.      *         will block.
  671.      *
  672.      * @see #setMaxWait
  673.      * @see #setBlockWhenExhausted
  674.      * @since 2.11.0
  675.      */
  676.     public final Duration getMaxWaitDuration() {
  677.         return maxWaitDuration;
  678.     }

  679.     /**
  680.      * Gets the maximum amount of time (in milliseconds) the
  681.      * {@code borrowObject()} method should block before throwing an
  682.      * exception when the pool is exhausted and
  683.      * {@link #getBlockWhenExhausted} is true. When less than 0, the
  684.      * {@code borrowObject()} method may block indefinitely.
  685.      *
  686.      * @return the maximum number of milliseconds {@code borrowObject()}
  687.      *         will block.
  688.      *
  689.      * @see #setMaxWait
  690.      * @see #setBlockWhenExhausted
  691.      * @deprecated Use {@link #getMaxWaitDuration()}.
  692.      */
  693.     @Deprecated
  694.     public final long getMaxWaitMillis() {
  695.         return maxWaitDuration.toMillis();
  696.     }

  697.     /**
  698.      * Gets the mean time objects are active for based on the last {@link
  699.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
  700.      * @return mean time an object has been checked out from the pool among
  701.      * recently returned objects.
  702.      *
  703.      * @since 2.12.0
  704.      */
  705.     public final Duration getMeanActiveDuration() {
  706.         return activeTimes.getMeanDuration();
  707.     }

  708.     /**
  709.      * Gets the mean time objects are active for based on the last {@link
  710.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
  711.      * @return mean time an object has been checked out from the pool among
  712.      * recently returned objects.
  713.      *
  714.      * @deprecated Use {@link #getMeanActiveDuration()}.
  715.      */
  716.     @Deprecated
  717.     public final long getMeanActiveTimeMillis() {
  718.         return activeTimes.getMean();
  719.     }

  720.     /**
  721.      * Gets the mean time threads wait to borrow an object based on the last {@link
  722.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
  723.      *
  724.      * @return mean time in milliseconds that a recently served thread has had
  725.      * to wait to borrow an object from the pool.
  726.      * @since 2.12.0
  727.      */
  728.     public final Duration getMeanBorrowWaitDuration() {
  729.         return waitTimes.getMeanDuration();
  730.     }

  731.     /**
  732.      * Gets the mean time threads wait to borrow an object based on the last {@link
  733.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
  734.      *
  735.      * @return mean time in milliseconds that a recently served thread has had
  736.      * to wait to borrow an object from the pool.
  737.      * @deprecated Use {@link #getMeanBorrowWaitDuration()}.
  738.      */
  739.     @Deprecated
  740.     public final long getMeanBorrowWaitTimeMillis() {
  741.         return waitTimes.getMean();
  742.     }

  743.     /**
  744.      * Gets the mean time objects are idle for based on the last {@link
  745.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
  746.      *
  747.      * @return mean time an object has been idle in the pool among recently
  748.      * borrowed objects.
  749.      * @since 2.12.0
  750.      */
  751.     public final Duration getMeanIdleDuration() {
  752.         return idleTimes.getMeanDuration();
  753.     }

  754.     /**
  755.      * Gets the mean time objects are idle for based on the last {@link
  756.      * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
  757.      *
  758.      * @return mean time an object has been idle in the pool among recently
  759.      * borrowed objects.
  760.      * @deprecated Use {@link #getMeanIdleDuration()}.
  761.      */
  762.     @Deprecated
  763.     public final long getMeanIdleTimeMillis() {
  764.         return idleTimes.getMean();
  765.     }

  766.     /**
  767.      * Gets whether to include statistics in exception messages.
  768.      * <p>
  769.      * Statistics may not accurately reflect snapshot state at the time of the exception because we do not want to lock the pool when gathering this
  770.      * information.
  771.      * </p>
  772.      *
  773.      * @return whether to include statistics in exception messages.
  774.      * @since 2.11.0
  775.      */
  776.     public boolean getMessageStatistics() {
  777.         return messageStatistics;
  778.     }

  779.     /**
  780.      * Gets the minimum amount of time an object may sit idle in the pool
  781.      * before it is eligible for eviction by the idle object evictor (if any -
  782.      * see {@link #setDurationBetweenEvictionRuns(Duration)}). When non-positive,
  783.      * no objects will be evicted from the pool due to idle time alone.
  784.      *
  785.      * @return minimum amount of time an object may sit idle in the pool before
  786.      *         it is eligible for eviction
  787.      *
  788.      * @see #setMinEvictableIdleTimeMillis
  789.      * @see #setTimeBetweenEvictionRunsMillis
  790.      * @since 2.11.0
  791.      */
  792.     public final Duration getMinEvictableIdleDuration() {
  793.         return minEvictableIdleDuration;
  794.     }

  795.     /**
  796.      * Gets the minimum amount of time an object may sit idle in the pool
  797.      * before it is eligible for eviction by the idle object evictor (if any -
  798.      * see {@link #setDurationBetweenEvictionRuns(Duration)}). When non-positive,
  799.      * no objects will be evicted from the pool due to idle time alone.
  800.      *
  801.      * @return minimum amount of time an object may sit idle in the pool before
  802.      *         it is eligible for eviction
  803.      *
  804.      * @see #setMinEvictableIdleTimeMillis
  805.      * @see #setTimeBetweenEvictionRunsMillis
  806.      * @since 2.10.0
  807.      * @deprecated Use {@link #getMinEvictableIdleDuration()}.
  808.      */
  809.     @Deprecated
  810.     public final Duration getMinEvictableIdleTime() {
  811.         return minEvictableIdleDuration;
  812.     }

  813.     /**
  814.      * Gets the minimum amount of time an object may sit idle in the pool
  815.      * before it is eligible for eviction by the idle object evictor (if any -
  816.      * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
  817.      * no objects will be evicted from the pool due to idle time alone.
  818.      *
  819.      * @return minimum amount of time an object may sit idle in the pool before
  820.      *         it is eligible for eviction
  821.      *
  822.      * @see #setMinEvictableIdleTimeMillis
  823.      * @see #setTimeBetweenEvictionRunsMillis
  824.      * @deprecated Use {@link #getMinEvictableIdleDuration()}.
  825.      */
  826.     @Deprecated
  827.     public final long getMinEvictableIdleTimeMillis() {
  828.         return minEvictableIdleDuration.toMillis();
  829.     }

  830.     /**
  831.      * Gets the number of instances currently idle in this pool.
  832.      * @return count of instances available for checkout from the pool
  833.      */
  834.     public abstract int getNumIdle();

  835.     /**
  836.      * Gets the maximum number of objects to examine during each run (if any)
  837.      * of the idle object evictor thread. When positive, the number of tests
  838.      * performed for a run will be the minimum of the configured value and the
  839.      * number of idle instances in the pool. When negative, the number of tests
  840.      * performed will be <code>ceil({@link #getNumIdle}/
  841.      * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
  842.      * value is {@code -n} roughly one nth of the idle objects will be
  843.      * tested per run.
  844.      *
  845.      * @return max number of objects to examine during each evictor run
  846.      * @see #setNumTestsPerEvictionRun
  847.      * @see #setTimeBetweenEvictionRunsMillis
  848.      */
  849.     public final int getNumTestsPerEvictionRun() {
  850.         return numTestsPerEvictionRun;
  851.     }

  852.     /**
  853.      * Gets whether a check is made for abandoned objects when an object is borrowed
  854.      * from this pool.
  855.      *
  856.      * @return {@code true} if abandoned object removal is configured to be
  857.      *         activated by borrowObject otherwise {@code false}
  858.      *
  859.      * @see AbandonedConfig#getRemoveAbandonedOnBorrow()
  860.      * @since 2.11.0
  861.      */
  862.     public boolean getRemoveAbandonedOnBorrow() {
  863.         final AbandonedConfig ac = this.abandonedConfig;
  864.         return ac != null && ac.getRemoveAbandonedOnBorrow();
  865.     }

  866.     /**
  867.      * Gets whether a check is made for abandoned objects when the evictor runs.
  868.      *
  869.      * @return {@code true} if abandoned object removal is configured to be
  870.      *         activated when the evictor runs otherwise {@code false}
  871.      *
  872.      * @see AbandonedConfig#getRemoveAbandonedOnMaintenance()
  873.      * @since 2.11.0
  874.      */
  875.     public boolean getRemoveAbandonedOnMaintenance() {
  876.         final AbandonedConfig ac = this.abandonedConfig;
  877.         return ac != null && ac.getRemoveAbandonedOnMaintenance();
  878.     }

  879.     /**
  880.      * Gets the timeout before which an object will be considered to be
  881.      * abandoned by this pool.
  882.      *
  883.      * @return The abandoned object timeout in seconds if abandoned object
  884.      *         removal is configured for this pool; Integer.MAX_VALUE otherwise.
  885.      *
  886.      * @see AbandonedConfig#getRemoveAbandonedTimeoutDuration()
  887.      * @see AbandonedConfig#getRemoveAbandonedTimeoutDuration()
  888.      * @deprecated Use {@link #getRemoveAbandonedTimeoutDuration()}.
  889.      * @since 2.11.0
  890.      */
  891.     @Deprecated
  892.     public int getRemoveAbandonedTimeout() {
  893.         return (int) getRemoveAbandonedTimeoutDuration().getSeconds();
  894.     }

  895.     /**
  896.      * Gets the timeout before which an object will be considered to be
  897.      * abandoned by this pool.
  898.      *
  899.      * @return The abandoned object timeout in seconds if abandoned object
  900.      *         removal is configured for this pool; Integer.MAX_VALUE otherwise.
  901.      *
  902.      * @see AbandonedConfig#getRemoveAbandonedTimeoutDuration()
  903.      * @since 2.11.0
  904.      */
  905.     public Duration getRemoveAbandonedTimeoutDuration() {
  906.         final AbandonedConfig ac = this.abandonedConfig;
  907.         return ac != null ? ac.getRemoveAbandonedTimeoutDuration() : DEFAULT_REMOVE_ABANDONED_TIMEOUT;
  908.     }

  909.     /**
  910.      * Gets the total number of objects returned to this pool over the lifetime of
  911.      * the pool. This excludes attempts to return the same object multiple
  912.      * times.
  913.      * @return the returned object count
  914.      */
  915.     public final long getReturnedCount() {
  916.         return returnedCount.get();
  917.     }

  918.     /**
  919.      * Gets the minimum amount of time an object may sit idle in the pool
  920.      * before it is eligible for eviction by the idle object evictor (if any -
  921.      * see {@link #setDurationBetweenEvictionRuns(Duration)}),
  922.      * with the extra condition that at least {@code minIdle} object
  923.      * instances remain in the pool. This setting is overridden by
  924.      * {@link #getMinEvictableIdleTime} (that is, if
  925.      * {@link #getMinEvictableIdleTime} is positive, then
  926.      * {@link #getSoftMinEvictableIdleTime} is ignored).
  927.      *
  928.      * @return minimum amount of time an object may sit idle in the pool before
  929.      *         it is eligible for eviction if minIdle instances are available
  930.      *
  931.      * @see #setSoftMinEvictableIdleDuration(Duration)
  932.      * @since 2.11.0
  933.      */
  934.     public final Duration getSoftMinEvictableIdleDuration() {
  935.         return softMinEvictableIdleDuration;
  936.     }

  937.     /**
  938.      * Gets the minimum amount of time an object may sit idle in the pool
  939.      * before it is eligible for eviction by the idle object evictor (if any -
  940.      * see {@link #setDurationBetweenEvictionRuns(Duration)}),
  941.      * with the extra condition that at least {@code minIdle} object
  942.      * instances remain in the pool. This setting is overridden by
  943.      * {@link #getMinEvictableIdleTime} (that is, if
  944.      * {@link #getMinEvictableIdleTime} is positive, then
  945.      * {@link #getSoftMinEvictableIdleTime} is ignored).
  946.      *
  947.      * @return minimum amount of time an object may sit idle in the pool before
  948.      *         it is eligible for eviction if minIdle instances are available
  949.      *
  950.      * @see #setSoftMinEvictableIdleDuration(Duration)
  951.      * @since 2.10.0
  952.      * @deprecated Use {@link #getSoftMinEvictableIdleDuration}.
  953.      */
  954.     @Deprecated
  955.     public final Duration getSoftMinEvictableIdleTime() {
  956.         return softMinEvictableIdleDuration;
  957.     }

  958.     /**
  959.      * Gets the minimum amount of time an object may sit idle in the pool
  960.      * before it is eligible for eviction by the idle object evictor (if any -
  961.      * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
  962.      * with the extra condition that at least {@code minIdle} object
  963.      * instances remain in the pool. This setting is overridden by
  964.      * {@link #getMinEvictableIdleTimeMillis} (that is, if
  965.      * {@link #getMinEvictableIdleTimeMillis} is positive, then
  966.      * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
  967.      *
  968.      * @return minimum amount of time an object may sit idle in the pool before
  969.      *         it is eligible for eviction if minIdle instances are available
  970.      *
  971.      * @see #setSoftMinEvictableIdleTimeMillis
  972.      * @deprecated Use {@link #getSoftMinEvictableIdleTime()}.
  973.      */
  974.     @Deprecated
  975.     public final long getSoftMinEvictableIdleTimeMillis() {
  976.         return softMinEvictableIdleDuration.toMillis();
  977.     }

  978.     /**
  979.      * Gets the stack trace of an exception as a string.
  980.      * @param e exception to trace
  981.      * @return exception stack trace as a string
  982.      */
  983.     private String getStackTrace(final Exception e) {
  984.         // Need the exception in string form to prevent the retention of
  985.         // references to classes in the stack trace that could trigger a memory
  986.         // leak in a container environment.
  987.         final Writer w = new StringWriter();
  988.         final PrintWriter pw = new PrintWriter(w);
  989.         e.printStackTrace(pw);
  990.         return w.toString();
  991.     }

  992.     /**
  993.      * Gets a statistics string.
  994.      *
  995.      * @return  a statistics string.
  996.      */
  997.     String getStatsString() {
  998.         // Simply listed in AB order.
  999.         return String.format(
  1000.                 "activeTimes=%s, blockWhenExhausted=%s, borrowedCount=%,d, closed=%s, createdCount=%,d, destroyedByBorrowValidationCount=%,d, " +
  1001.                         "destroyedByEvictorCount=%,d, evictorShutdownTimeoutDuration=%s, fairness=%s, idleTimes=%s, lifo=%s, maxBorrowWaitDuration=%s, " +
  1002.                         "maxTotal=%s, maxWaitDuration=%s, minEvictableIdleDuration=%s, numTestsPerEvictionRun=%s, returnedCount=%s, " +
  1003.                         "softMinEvictableIdleDuration=%s, testOnBorrow=%s, testOnCreate=%s, testOnReturn=%s, testWhileIdle=%s, " +
  1004.                         "durationBetweenEvictionRuns=%s, waitTimes=%s",
  1005.                 activeTimes.getValues(), blockWhenExhausted, borrowedCount.get(), closed, createdCount.get(), destroyedByBorrowValidationCount.get(),
  1006.                 destroyedByEvictorCount.get(), evictorShutdownTimeoutDuration, fairness, idleTimes.getValues(), lifo, maxBorrowWaitDuration.get(),
  1007.                 maxTotal, maxWaitDuration, minEvictableIdleDuration, numTestsPerEvictionRun, returnedCount, softMinEvictableIdleDuration, testOnBorrow,
  1008.                 testOnCreate, testOnReturn, testWhileIdle, durationBetweenEvictionRuns, waitTimes.getValues());
  1009.     }

  1010.     /**
  1011.      * Gets the listener used (if any) to receive notifications of exceptions
  1012.      * unavoidably swallowed by the pool.
  1013.      *
  1014.      * @return The listener or {@code null} for no listener
  1015.      */
  1016.     public final SwallowedExceptionListener getSwallowedExceptionListener() {
  1017.         return swallowedExceptionListener;
  1018.     }

  1019.     /**
  1020.      * Gets whether objects borrowed from the pool will be validated before
  1021.      * being returned from the {@code borrowObject()} method. Validation is
  1022.      * performed by the {@code validateObject()} method of the factory
  1023.      * associated with the pool. If the object fails to validate, it will be
  1024.      * removed from the pool and destroyed, and a new attempt will be made to
  1025.      * borrow an object from the pool.
  1026.      *
  1027.      * @return {@code true} if objects are validated before being returned
  1028.      *         from the {@code borrowObject()} method
  1029.      *
  1030.      * @see #setTestOnBorrow
  1031.      */
  1032.     public final boolean getTestOnBorrow() {
  1033.         return testOnBorrow;
  1034.     }

  1035.     /**
  1036.      * Gets whether objects created for the pool will be validated before
  1037.      * being returned from the {@code borrowObject()} method. Validation is
  1038.      * performed by the {@code validateObject()} method of the factory
  1039.      * associated with the pool. If the object fails to validate, then
  1040.      * {@code borrowObject()} will fail.
  1041.      *
  1042.      * @return {@code true} if newly created objects are validated before
  1043.      *         being returned from the {@code borrowObject()} method
  1044.      *
  1045.      * @see #setTestOnCreate
  1046.      * @since 2.2
  1047.      */
  1048.     public final boolean getTestOnCreate() {
  1049.         return testOnCreate;
  1050.     }

  1051.     /**
  1052.      * Gets whether objects borrowed from the pool will be validated when
  1053.      * they are returned to the pool via the {@code returnObject()} method.
  1054.      * Validation is performed by the {@code validateObject()} method of
  1055.      * the factory associated with the pool. Returning objects that fail validation
  1056.      * are destroyed rather then being returned the pool.
  1057.      *
  1058.      * @return {@code true} if objects are validated on return to
  1059.      *         the pool via the {@code returnObject()} method
  1060.      *
  1061.      * @see #setTestOnReturn
  1062.      */
  1063.     public final boolean getTestOnReturn() {
  1064.         return testOnReturn;
  1065.     }

  1066.     /**
  1067.      * Gets whether objects sitting idle in the pool will be validated by the
  1068.      * idle object evictor (if any - see
  1069.      * {@link #setDurationBetweenEvictionRuns(Duration)}). Validation is performed
  1070.      * by the {@code validateObject()} method of the factory associated
  1071.      * with the pool. If the object fails to validate, it will be removed from
  1072.      * the pool and destroyed.
  1073.      *
  1074.      * @return {@code true} if objects will be validated by the evictor
  1075.      * @see #setTestWhileIdle
  1076.      * @see #setTimeBetweenEvictionRunsMillis
  1077.      */
  1078.     public final boolean getTestWhileIdle() {
  1079.         return testWhileIdle;
  1080.     }

  1081.     /**
  1082.      * Gets the duration to sleep between runs of the idle
  1083.      * object evictor thread. When non-positive, no idle object evictor thread
  1084.      * will be run.
  1085.      *
  1086.      * @return number of milliseconds to sleep between evictor runs
  1087.      * @see #setTimeBetweenEvictionRuns
  1088.      * @since 2.10.0
  1089.      * @deprecated {@link #getDurationBetweenEvictionRuns()}.
  1090.      */
  1091.     @Deprecated
  1092.     public final Duration getTimeBetweenEvictionRuns() {
  1093.         return durationBetweenEvictionRuns;
  1094.     }

  1095.     /**
  1096.      * Gets the number of milliseconds to sleep between runs of the idle
  1097.      * object evictor thread. When non-positive, no idle object evictor thread
  1098.      * will be run.
  1099.      *
  1100.      * @return number of milliseconds to sleep between evictor runs
  1101.      * @see #setTimeBetweenEvictionRunsMillis
  1102.      * @deprecated Use {@link #getDurationBetweenEvictionRuns()}.
  1103.      */
  1104.     @Deprecated
  1105.     public final long getTimeBetweenEvictionRunsMillis() {
  1106.         return durationBetweenEvictionRuns.toMillis();
  1107.     }

  1108.     /**
  1109.      * Tests whether or not abandoned object removal is configured for this pool.
  1110.      *
  1111.      * @return true if this pool is configured to detect and remove
  1112.      * abandoned objects
  1113.      * @since 2.11.0
  1114.      */
  1115.     public boolean isAbandonedConfig() {
  1116.         return abandonedConfig != null;
  1117.     }

  1118.     /**
  1119.      * Tests whether this pool instance been closed.
  1120.      * @return {@code true} when this pool has been closed.
  1121.      */
  1122.     public final boolean isClosed() {
  1123.         return closed;
  1124.     }

  1125.     /**
  1126.      * Registers the pool with the platform MBean server.
  1127.      * The registered name will be
  1128.      * {@code jmxNameBase + jmxNamePrefix + i} where i is the least
  1129.      * integer greater than or equal to 1 such that the name is not already
  1130.      * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
  1131.      * returning null.
  1132.      *
  1133.      * @param config Pool configuration
  1134.      * @param jmxNameBase default base JMX name for this pool
  1135.      * @param jmxNamePrefix name prefix
  1136.      * @return registered ObjectName, null if registration fails
  1137.      */
  1138.     private ObjectName jmxRegister(final BaseObjectPoolConfig<T> config,
  1139.             final String jmxNameBase, String jmxNamePrefix) {
  1140.         ObjectName newObjectName = null;
  1141.         final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
  1142.         int i = 1;
  1143.         boolean registered = false;
  1144.         String base = config.getJmxNameBase();
  1145.         if (base == null) {
  1146.             base = jmxNameBase;
  1147.         }
  1148.         while (!registered) {
  1149.             try {
  1150.                 ObjectName objName;
  1151.                 // Skip the numeric suffix for the first pool in case there is
  1152.                 // only one so the names are cleaner.
  1153.                 if (i == 1) {
  1154.                     objName = new ObjectName(base + jmxNamePrefix);
  1155.                 } else {
  1156.                     objName = new ObjectName(base + jmxNamePrefix + i);
  1157.                 }
  1158.                 if (!mbs.isRegistered(objName)) {
  1159.                     mbs.registerMBean(this, objName);
  1160.                     newObjectName = objName;
  1161.                     registered = true;
  1162.                 } else {
  1163.                     // Increment the index and try again
  1164.                     i++;
  1165.                 }
  1166.             } catch (final MalformedObjectNameException e) {
  1167.                 if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals(
  1168.                         jmxNamePrefix) && jmxNameBase.equals(base)) {
  1169.                     // Shouldn't happen. Skip registration if it does.
  1170.                     registered = true;
  1171.                 } else {
  1172.                     // Must be an invalid name. Use the defaults instead.
  1173.                     jmxNamePrefix =
  1174.                             BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX;
  1175.                     base = jmxNameBase;
  1176.                 }
  1177.             } catch (final InstanceAlreadyExistsException e) {
  1178.                 // Increment the index and try again
  1179.                 i++;
  1180.             } catch (final MBeanRegistrationException | NotCompliantMBeanException e) {
  1181.                 // Shouldn't happen. Skip registration if it does.
  1182.                 registered = true;
  1183.             }
  1184.         }
  1185.         return newObjectName;
  1186.     }

  1187.     /**
  1188.      * Unregisters this pool's MBean.
  1189.      */
  1190.     final void jmxUnregister() {
  1191.         if (objectName != null) {
  1192.             try {
  1193.                 ManagementFactory.getPlatformMBeanServer().unregisterMBean(objectName);
  1194.             } catch (final MBeanRegistrationException | InstanceNotFoundException e) {
  1195.                 swallowException(e);
  1196.             }
  1197.         }
  1198.     }

  1199.     /**
  1200.      * Marks the object as returning to the pool.
  1201.      * @param pooledObject instance to return to the keyed pool
  1202.      */
  1203.     protected void markReturningState(final PooledObject<T> pooledObject) {
  1204.         synchronized (pooledObject) {
  1205.             if (pooledObject.getState() != PooledObjectState.ALLOCATED) {
  1206.                 throw new IllegalStateException("Object has already been returned to this pool or is invalid");
  1207.             }
  1208.             pooledObject.markReturning(); // Keep from being marked abandoned
  1209.         }
  1210.     }

  1211.     /**
  1212.      * Sets the abandoned object removal configuration.
  1213.      *
  1214.      * @param abandonedConfig the new configuration to use. This is used by value.
  1215.      * @see AbandonedConfig
  1216.      * @since 2.11.0
  1217.      */
  1218.     public void setAbandonedConfig(final AbandonedConfig abandonedConfig) {
  1219.         this.abandonedConfig = AbandonedConfig.copy(abandonedConfig);
  1220.     }

  1221.     /**
  1222.      * Sets whether to block when the {@code borrowObject()} method is
  1223.      * invoked when the pool is exhausted (the maximum number of "active"
  1224.      * objects has been reached).
  1225.      *
  1226.      * @param blockWhenExhausted    {@code true} if
  1227.      *                              {@code borrowObject()} should block
  1228.      *                              when the pool is exhausted
  1229.      *
  1230.      * @see #getBlockWhenExhausted
  1231.      */
  1232.     public final void setBlockWhenExhausted(final boolean blockWhenExhausted) {
  1233.         this.blockWhenExhausted = blockWhenExhausted;
  1234.     }

  1235.     /**
  1236.      * Sets the receiver with the given configuration.
  1237.      *
  1238.      * @param config Initialization source.
  1239.      */
  1240.     protected void setConfig(final BaseObjectPoolConfig<T> config) {
  1241.         setLifo(config.getLifo());
  1242.         setMaxWait(config.getMaxWaitDuration());
  1243.         setBlockWhenExhausted(config.getBlockWhenExhausted());
  1244.         setTestOnCreate(config.getTestOnCreate());
  1245.         setTestOnBorrow(config.getTestOnBorrow());
  1246.         setTestOnReturn(config.getTestOnReturn());
  1247.         setTestWhileIdle(config.getTestWhileIdle());
  1248.         setNumTestsPerEvictionRun(config.getNumTestsPerEvictionRun());
  1249.         setMinEvictableIdleDuration(config.getMinEvictableIdleDuration());
  1250.         setDurationBetweenEvictionRuns(config.getDurationBetweenEvictionRuns());
  1251.         setSoftMinEvictableIdleDuration(config.getSoftMinEvictableIdleDuration());
  1252.         final EvictionPolicy<T> policy = config.getEvictionPolicy();
  1253.         if (policy == null) {
  1254.             // Use the class name (pre-2.6.0 compatible)
  1255.             setEvictionPolicyClassName(config.getEvictionPolicyClassName());
  1256.         } else {
  1257.             // Otherwise, use the class (2.6.0 feature)
  1258.             setEvictionPolicy(policy);
  1259.         }
  1260.         setEvictorShutdownTimeout(config.getEvictorShutdownTimeoutDuration());
  1261.     }

  1262.     /**
  1263.      * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
  1264.      * <ul>
  1265.      * <li>When positive, the idle object evictor thread starts.</li>
  1266.      * <li>When null or non-positive, no idle object evictor thread runs.</li>
  1267.      * </ul>
  1268.      *
  1269.      * @param timeBetweenEvictionRuns
  1270.      *            duration to sleep between evictor runs
  1271.      *
  1272.      * @see #getDurationBetweenEvictionRuns()
  1273.      * @since 2.12.0
  1274.      */
  1275.     public final void setDurationBetweenEvictionRuns(final Duration timeBetweenEvictionRuns) {
  1276.         this.durationBetweenEvictionRuns = PoolImplUtils.nonNull(timeBetweenEvictionRuns, BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS);
  1277.         startEvictor(this.durationBetweenEvictionRuns);
  1278.     }

  1279.     /**
  1280.      * Sets the eviction policy for this pool.
  1281.      *
  1282.      * @param evictionPolicy
  1283.      *            the eviction policy for this pool.
  1284.      * @since 2.6.0
  1285.      */
  1286.     public void setEvictionPolicy(final EvictionPolicy<T> evictionPolicy) {
  1287.         this.evictionPolicy = evictionPolicy;
  1288.     }

  1289.     /**
  1290.      * Sets the eviction policy.
  1291.      *
  1292.      * @param className Eviction policy class name.
  1293.      * @param classLoader Load the class from this class loader.
  1294.      * @throws LinkageError if the linkage fails
  1295.      * @throws ExceptionInInitializerError if the initialization provoked by this method fails
  1296.      * @throws ClassNotFoundException if the class cannot be located by the specified class loader
  1297.      * @throws IllegalAccessException if this {@code Constructor} object is enforcing Java language access control and the underlying constructor is
  1298.      *         inaccessible.
  1299.      * @throws IllegalArgumentException if the number of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or if,
  1300.      *         after possible unwrapping, a parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion; if
  1301.      *         this constructor pertains to an enum type.
  1302.      * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class.
  1303.      * @throws InvocationTargetException if the underlying constructor throws an exception.
  1304.      * @throws ExceptionInInitializerError if the initialization provoked by this method fails.
  1305.      * @throws NoSuchMethodException if a matching method is not found.
  1306.      * @throws SecurityException If a security manage is present and the caller's class loader is not the same as or an ancestor of the class loader for the
  1307.      *         current class and invocation of {@link SecurityManager#checkPackageAccess s.checkPackageAccess()} denies access to the package of this class.
  1308.      */
  1309.     @SuppressWarnings("unchecked")
  1310.     private void setEvictionPolicy(final String className, final ClassLoader classLoader)
  1311.             throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  1312.         final Class<?> clazz = Class.forName(className, true, classLoader);
  1313.         final Object policy = clazz.getConstructor().newInstance();
  1314.         this.evictionPolicy = (EvictionPolicy<T>) policy;
  1315.     }

  1316.     /**
  1317.      * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
  1318.      * load the class using the thread context class loader. If that fails, the use the class loader for the
  1319.      * {@link EvictionPolicy} interface.
  1320.      *
  1321.      * @param evictionPolicyClassName
  1322.      *            the fully qualified class name of the new eviction policy
  1323.      *
  1324.      * @see #getEvictionPolicyClassName()
  1325.      * @since 2.6.0 If loading the class using the thread context class loader fails, use the class loader for the
  1326.      *        {@link EvictionPolicy} interface.
  1327.      */
  1328.     public final void setEvictionPolicyClassName(final String evictionPolicyClassName) {
  1329.         setEvictionPolicyClassName(evictionPolicyClassName, Thread.currentThread().getContextClassLoader());
  1330.     }

  1331.     /**
  1332.      * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
  1333.      * load the class using the given class loader. If that fails, use the class loader for the {@link EvictionPolicy}
  1334.      * interface.
  1335.      *
  1336.      * @param evictionPolicyClassName
  1337.      *            the fully qualified class name of the new eviction policy
  1338.      * @param classLoader
  1339.      *            the class loader to load the given {@code evictionPolicyClassName}.
  1340.      *
  1341.      * @see #getEvictionPolicyClassName()
  1342.      * @since 2.6.0 If loading the class using the given class loader fails, use the class loader for the
  1343.      *        {@link EvictionPolicy} interface.
  1344.      */
  1345.     public final void setEvictionPolicyClassName(final String evictionPolicyClassName, final ClassLoader classLoader) {
  1346.         // Getting epClass here and now best matches the caller's environment
  1347.         final Class<?> epClass = EvictionPolicy.class;
  1348.         final ClassLoader epClassLoader = epClass.getClassLoader();
  1349.         try {
  1350.             try {
  1351.                 setEvictionPolicy(evictionPolicyClassName, classLoader);
  1352.             } catch (final ClassCastException | ClassNotFoundException e) {
  1353.                 setEvictionPolicy(evictionPolicyClassName, epClassLoader);
  1354.             }
  1355.         } catch (final ClassCastException e) {
  1356.             throw new IllegalArgumentException("Class " + evictionPolicyClassName + " from class loaders [" +
  1357.                     classLoader + ", " + epClassLoader + "] do not implement " + EVICTION_POLICY_TYPE_NAME);
  1358.         } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException |
  1359.                 InvocationTargetException | NoSuchMethodException e) {
  1360.             throw new IllegalArgumentException(
  1361.                     "Unable to create " + EVICTION_POLICY_TYPE_NAME + " instance of type " + evictionPolicyClassName,
  1362.                     e);
  1363.         }
  1364.     }

  1365.     /**
  1366.      * Sets the timeout that will be used when waiting for the Evictor to shutdown if this pool is closed and it is the
  1367.      * only pool still using the value for the Evictor.
  1368.      *
  1369.      * @param evictorShutdownTimeout the timeout in milliseconds that will be used while waiting for the Evictor
  1370.      *                                     to shut down.
  1371.      * @since 2.10.0
  1372.      */
  1373.     public final void setEvictorShutdownTimeout(final Duration evictorShutdownTimeout) {
  1374.         this.evictorShutdownTimeoutDuration = PoolImplUtils.nonNull(evictorShutdownTimeout, BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT);
  1375.     }

  1376.     /**
  1377.      * Sets the timeout that will be used when waiting for the Evictor to shutdown if this pool is closed and it is the
  1378.      * only pool still using the value for the Evictor.
  1379.      *
  1380.      * @param evictorShutdownTimeoutMillis the timeout in milliseconds that will be used while waiting for the Evictor
  1381.      *                                     to shut down.
  1382.      * @deprecated Use {@link #setEvictorShutdownTimeout(Duration)}.
  1383.      */
  1384.     @Deprecated
  1385.     public final void setEvictorShutdownTimeoutMillis(final long evictorShutdownTimeoutMillis) {
  1386.         setEvictorShutdownTimeout(Duration.ofMillis(evictorShutdownTimeoutMillis));
  1387.     }

  1388.     /**
  1389.      * Sets whether the pool has LIFO (last in, first out) behavior with
  1390.      * respect to idle objects - always returning the most recently used object
  1391.      * from the pool, or as a FIFO (first in, first out) queue, where the pool
  1392.      * always returns the oldest object in the idle object pool.
  1393.      *
  1394.      * @param lifo  {@code true} if the pool is to be configured with LIFO
  1395.      *              behavior or {@code false} if the pool is to be
  1396.      *              configured with FIFO behavior
  1397.      *
  1398.      * @see #getLifo()
  1399.      */
  1400.     public final void setLifo(final boolean lifo) {
  1401.         this.lifo = lifo;
  1402.     }

  1403.     /**
  1404.      * Sets the cap on the number of objects that can be allocated by the pool
  1405.      * (checked out to clients, or idle awaiting checkout) at a given time. Use
  1406.      * a negative value for no limit.
  1407.      *
  1408.      * @param maxTotal  The cap on the total number of object instances managed
  1409.      *                  by the pool. Negative values mean that there is no limit
  1410.      *                  to the number of objects allocated by the pool.
  1411.      *
  1412.      * @see #getMaxTotal
  1413.      */
  1414.     public final void setMaxTotal(final int maxTotal) {
  1415.         this.maxTotal = maxTotal;
  1416.     }

  1417.     /**
  1418.      * Sets the maximum duration the
  1419.      * {@code borrowObject()} method should block before throwing an
  1420.      * exception when the pool is exhausted and
  1421.      * {@link #getBlockWhenExhausted} is true. When less than 0, the
  1422.      * {@code borrowObject()} method may block indefinitely.
  1423.      *
  1424.      * @param maxWaitDuration the maximum duration
  1425.      *                      {@code borrowObject()} will block or negative
  1426.      *                      for indefinitely.
  1427.      *
  1428.      * @see #getMaxWaitDuration
  1429.      * @see #setBlockWhenExhausted
  1430.      * @since 2.11.0
  1431.      */
  1432.     public final void setMaxWait(final Duration maxWaitDuration) {
  1433.         this.maxWaitDuration = PoolImplUtils.nonNull(maxWaitDuration, BaseObjectPoolConfig.DEFAULT_MAX_WAIT);
  1434.     }

  1435.     /**
  1436.      * Sets the maximum amount of time (in milliseconds) the
  1437.      * {@code borrowObject()} method should block before throwing an
  1438.      * exception when the pool is exhausted and
  1439.      * {@link #getBlockWhenExhausted} is true. When less than 0, the
  1440.      * {@code borrowObject()} method may block indefinitely.
  1441.      *
  1442.      * @param maxWaitMillis the maximum number of milliseconds
  1443.      *                      {@code borrowObject()} will block or negative
  1444.      *                      for indefinitely.
  1445.      *
  1446.      * @see #getMaxWaitDuration
  1447.      * @see #setBlockWhenExhausted
  1448.      * @deprecated Use {@link #setMaxWait}.
  1449.      */
  1450.     @Deprecated
  1451.     public final void setMaxWaitMillis(final long maxWaitMillis) {
  1452.         setMaxWait(Duration.ofMillis(maxWaitMillis));
  1453.     }

  1454.     /**
  1455.      * Sets whether to include statistics in exception messages.
  1456.      * <p>
  1457.      * Statistics may not accurately reflect snapshot state at the time of the exception because we do not want to lock the pool when gathering this
  1458.      * information.
  1459.      * </p>
  1460.      *
  1461.      * @param messagesDetails whether to include statistics in exception messages.
  1462.      * @since 2.11.0
  1463.      */
  1464.     public void setMessagesStatistics(final boolean messagesDetails) {
  1465.         this.messageStatistics = messagesDetails;
  1466.     }

  1467.     /**
  1468.      * Sets the minimum amount of time an object may sit idle in the pool
  1469.      * before it is eligible for eviction by the idle object evictor (if any -
  1470.      * see {@link #setDurationBetweenEvictionRuns(Duration)}). When non-positive,
  1471.      * no objects will be evicted from the pool due to idle time alone.
  1472.      *
  1473.      * @param minEvictableIdleTime
  1474.      *            minimum amount of time an object may sit idle in the pool
  1475.      *            before it is eligible for eviction
  1476.      *
  1477.      * @see #getMinEvictableIdleTime
  1478.      * @see #setTimeBetweenEvictionRuns
  1479.      * @since 2.11.0
  1480.      * @deprecated Use {@link #setMinEvictableIdleDuration(Duration)}.
  1481.      */
  1482.     @Deprecated
  1483.     public final void setMinEvictableIdle(final Duration minEvictableIdleTime) {
  1484.         this.minEvictableIdleDuration = PoolImplUtils.nonNull(minEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION);
  1485.     }

  1486.     /**
  1487.      * Sets the minimum amount of time an object may sit idle in the pool
  1488.      * before it is eligible for eviction by the idle object evictor (if any -
  1489.      * see {@link #setDurationBetweenEvictionRuns(Duration)}). When non-positive,
  1490.      * no objects will be evicted from the pool due to idle time alone.
  1491.      *
  1492.      * @param minEvictableIdleTime
  1493.      *            minimum amount of time an object may sit idle in the pool
  1494.      *            before it is eligible for eviction
  1495.      *
  1496.      * @see #getMinEvictableIdleTime
  1497.      * @see #setTimeBetweenEvictionRuns
  1498.      * @since 2.12.0
  1499.      */
  1500.     public final void setMinEvictableIdleDuration(final Duration minEvictableIdleTime) {
  1501.         this.minEvictableIdleDuration = PoolImplUtils.nonNull(minEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION);
  1502.     }

  1503.     /**
  1504.      * Sets the minimum amount of time an object may sit idle in the pool
  1505.      * before it is eligible for eviction by the idle object evictor (if any -
  1506.      * see {@link #setDurationBetweenEvictionRuns(Duration)}). When non-positive,
  1507.      * no objects will be evicted from the pool due to idle time alone.
  1508.      *
  1509.      * @param minEvictableIdleTime
  1510.      *            minimum amount of time an object may sit idle in the pool
  1511.      *            before it is eligible for eviction
  1512.      *
  1513.      * @see #getMinEvictableIdleTime
  1514.      * @see #setTimeBetweenEvictionRuns
  1515.      * @since 2.10.0
  1516.      * @deprecated Use {@link #setMinEvictableIdleDuration(Duration)}.
  1517.      */
  1518.     @Deprecated
  1519.     public final void setMinEvictableIdleTime(final Duration minEvictableIdleTime) {
  1520.         this.minEvictableIdleDuration = PoolImplUtils.nonNull(minEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION);
  1521.     }

  1522.     /**
  1523.      * Sets the minimum amount of time an object may sit idle in the pool
  1524.      * before it is eligible for eviction by the idle object evictor (if any -
  1525.      * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
  1526.      * no objects will be evicted from the pool due to idle time alone.
  1527.      *
  1528.      * @param minEvictableIdleTimeMillis
  1529.      *            minimum amount of time an object may sit idle in the pool
  1530.      *            before it is eligible for eviction
  1531.      *
  1532.      * @see #getMinEvictableIdleTimeMillis
  1533.      * @see #setTimeBetweenEvictionRunsMillis
  1534.      * @deprecated Use {@link #setMinEvictableIdleTime(Duration)}.
  1535.      */
  1536.     @Deprecated
  1537.     public final void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
  1538.         setMinEvictableIdleTime(Duration.ofMillis(minEvictableIdleTimeMillis));
  1539.     }

  1540.     /**
  1541.      * Sets the maximum number of objects to examine during each run (if any)
  1542.      * of the idle object evictor thread. When positive, the number of tests
  1543.      * performed for a run will be the minimum of the configured value and the
  1544.      * number of idle instances in the pool. When negative, the number of tests
  1545.      * performed will be <code>ceil({@link #getNumIdle}/
  1546.      * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
  1547.      * value is {@code -n} roughly one nth of the idle objects will be
  1548.      * tested per run.
  1549.      *
  1550.      * @param numTestsPerEvictionRun
  1551.      *            max number of objects to examine during each evictor run
  1552.      *
  1553.      * @see #getNumTestsPerEvictionRun
  1554.      * @see #setTimeBetweenEvictionRunsMillis
  1555.      */
  1556.     public final void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
  1557.         this.numTestsPerEvictionRun = numTestsPerEvictionRun;
  1558.     }

  1559.     /**
  1560.      * Sets the minimum amount of time an object may sit idle in the pool
  1561.      * before it is eligible for eviction by the idle object evictor (if any -
  1562.      * see {@link #setDurationBetweenEvictionRuns(Duration)}),
  1563.      * with the extra condition that at least {@code minIdle} object
  1564.      * instances remain in the pool. This setting is overridden by
  1565.      * {@link #getMinEvictableIdleTime} (that is, if
  1566.      * {@link #getMinEvictableIdleTime} is positive, then
  1567.      * {@link #getSoftMinEvictableIdleTime} is ignored).
  1568.      *
  1569.      * @param softMinEvictableIdleTime
  1570.      *            minimum amount of time an object may sit idle in the pool
  1571.      *            before it is eligible for eviction if minIdle instances are
  1572.      *            available
  1573.      *
  1574.      * @see #getSoftMinEvictableIdleTimeMillis
  1575.      * @since 2.11.0
  1576.      * @deprecated Use {@link #setSoftMinEvictableIdleDuration(Duration)}.
  1577.      */
  1578.     @Deprecated
  1579.     public final void setSoftMinEvictableIdle(final Duration softMinEvictableIdleTime) {
  1580.         this.softMinEvictableIdleDuration = PoolImplUtils.nonNull(softMinEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION);
  1581.     }

  1582.     /**
  1583.      * Sets the minimum amount of time an object may sit idle in the pool
  1584.      * before it is eligible for eviction by the idle object evictor (if any -
  1585.      * see {@link #setDurationBetweenEvictionRuns(Duration)}),
  1586.      * with the extra condition that at least {@code minIdle} object
  1587.      * instances remain in the pool. This setting is overridden by
  1588.      * {@link #getMinEvictableIdleTime} (that is, if
  1589.      * {@link #getMinEvictableIdleTime} is positive, then
  1590.      * {@link #getSoftMinEvictableIdleTime} is ignored).
  1591.      *
  1592.      * @param softMinEvictableIdleTime
  1593.      *            minimum amount of time an object may sit idle in the pool
  1594.      *            before it is eligible for eviction if minIdle instances are
  1595.      *            available
  1596.      *
  1597.      * @see #getSoftMinEvictableIdleTimeMillis
  1598.      * @since 2.12.0
  1599.      */
  1600.     public final void setSoftMinEvictableIdleDuration(final Duration softMinEvictableIdleTime) {
  1601.         this.softMinEvictableIdleDuration = PoolImplUtils.nonNull(softMinEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION);
  1602.     }

  1603.     /**
  1604.      * Sets the minimum amount of time an object may sit idle in the pool
  1605.      * before it is eligible for eviction by the idle object evictor (if any -
  1606.      * see {@link #setDurationBetweenEvictionRuns(Duration)}),
  1607.      * with the extra condition that at least {@code minIdle} object
  1608.      * instances remain in the pool. This setting is overridden by
  1609.      * {@link #getMinEvictableIdleTime} (that is, if
  1610.      * {@link #getMinEvictableIdleTime} is positive, then
  1611.      * {@link #getSoftMinEvictableIdleTime} is ignored).
  1612.      *
  1613.      * @param softMinEvictableIdleTime
  1614.      *            minimum amount of time an object may sit idle in the pool
  1615.      *            before it is eligible for eviction if minIdle instances are
  1616.      *            available
  1617.      *
  1618.      * @see #getSoftMinEvictableIdleTimeMillis
  1619.      * @since 2.10.0
  1620.      * @deprecated Use {@link #setSoftMinEvictableIdleDuration(Duration)}.
  1621.      */
  1622.     @Deprecated
  1623.     public final void setSoftMinEvictableIdleTime(final Duration softMinEvictableIdleTime) {
  1624.         this.softMinEvictableIdleDuration = PoolImplUtils.nonNull(softMinEvictableIdleTime, BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION);
  1625.     }

  1626.     /**
  1627.      * Sets the minimum amount of time an object may sit idle in the pool
  1628.      * before it is eligible for eviction by the idle object evictor (if any -
  1629.      * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
  1630.      * with the extra condition that at least {@code minIdle} object
  1631.      * instances remain in the pool. This setting is overridden by
  1632.      * {@link #getMinEvictableIdleTimeMillis} (that is, if
  1633.      * {@link #getMinEvictableIdleTimeMillis} is positive, then
  1634.      * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
  1635.      *
  1636.      * @param softMinEvictableIdleTimeMillis
  1637.      *            minimum amount of time an object may sit idle in the pool
  1638.      *            before it is eligible for eviction if minIdle instances are
  1639.      *            available
  1640.      *
  1641.      * @see #getSoftMinEvictableIdleTimeMillis
  1642.      * @deprecated Use {@link #setSoftMinEvictableIdleDuration(Duration)}.
  1643.      */
  1644.     @Deprecated
  1645.     public final void setSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) {
  1646.         setSoftMinEvictableIdleTime(Duration.ofMillis(softMinEvictableIdleTimeMillis));
  1647.     }

  1648.     /**
  1649.      * Sets the listener used (if any) to receive notifications of exceptions
  1650.      * unavoidably swallowed by the pool.
  1651.      *
  1652.      * @param swallowedExceptionListener    The listener or {@code null}
  1653.      *                                      for no listener
  1654.      */
  1655.     public final void setSwallowedExceptionListener(
  1656.             final SwallowedExceptionListener swallowedExceptionListener) {
  1657.         this.swallowedExceptionListener = swallowedExceptionListener;
  1658.     }

  1659.     /**
  1660.      * Sets whether objects borrowed from the pool will be validated before
  1661.      * being returned from the {@code borrowObject()} method. Validation is
  1662.      * performed by the {@code validateObject()} method of the factory
  1663.      * associated with the pool. If the object fails to validate, it will be
  1664.      * removed from the pool and destroyed, and a new attempt will be made to
  1665.      * borrow an object from the pool.
  1666.      *
  1667.      * @param testOnBorrow  {@code true} if objects should be validated
  1668.      *                      before being returned from the
  1669.      *                      {@code borrowObject()} method
  1670.      *
  1671.      * @see #getTestOnBorrow
  1672.      */
  1673.     public final void setTestOnBorrow(final boolean testOnBorrow) {
  1674.         this.testOnBorrow = testOnBorrow;
  1675.     }

  1676.     /**
  1677.      * Sets whether objects created for the pool will be validated before
  1678.      * being returned from the {@code borrowObject()} method. Validation is
  1679.      * performed by the {@code validateObject()} method of the factory
  1680.      * associated with the pool. If the object fails to validate, then
  1681.      * {@code borrowObject()} will fail.
  1682.      *
  1683.      * @param testOnCreate  {@code true} if newly created objects should be
  1684.      *                      validated before being returned from the
  1685.      *                      {@code borrowObject()} method
  1686.      *
  1687.      * @see #getTestOnCreate
  1688.      * @since 2.2
  1689.      */
  1690.     public final void setTestOnCreate(final boolean testOnCreate) {
  1691.         this.testOnCreate = testOnCreate;
  1692.     }

  1693.     /**
  1694.      * Sets whether objects borrowed from the pool will be validated when
  1695.      * they are returned to the pool via the {@code returnObject()} method.
  1696.      * Validation is performed by the {@code validateObject()} method of
  1697.      * the factory associated with the pool. Returning objects that fail validation
  1698.      * are destroyed rather then being returned the pool.
  1699.      *
  1700.      * @param testOnReturn {@code true} if objects are validated on
  1701.      *                     return to the pool via the
  1702.      *                     {@code returnObject()} method
  1703.      *
  1704.      * @see #getTestOnReturn
  1705.      */
  1706.     public final void setTestOnReturn(final boolean testOnReturn) {
  1707.         this.testOnReturn = testOnReturn;
  1708.     }

  1709.     /**
  1710.      * Sets whether objects sitting idle in the pool will be validated by the
  1711.      * idle object evictor (if any - see
  1712.      * {@link #setDurationBetweenEvictionRuns(Duration)}). Validation is performed
  1713.      * by the {@code validateObject()} method of the factory associated
  1714.      * with the pool. If the object fails to validate, it will be removed from
  1715.      * the pool and destroyed.  Note that setting this property has no effect
  1716.      * unless the idle object evictor is enabled by setting
  1717.      * {@code timeBetweenEvictionRunsMillis} to a positive value.
  1718.      *
  1719.      * @param testWhileIdle
  1720.      *            {@code true} so objects will be validated by the evictor
  1721.      *
  1722.      * @see #getTestWhileIdle
  1723.      * @see #setTimeBetweenEvictionRuns
  1724.      */
  1725.     public final void setTestWhileIdle(final boolean testWhileIdle) {
  1726.         this.testWhileIdle = testWhileIdle;
  1727.     }

  1728.     /**
  1729.      * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
  1730.      * <ul>
  1731.      * <li>When positive, the idle object evictor thread starts.</li>
  1732.      * <li>When non-positive, no idle object evictor thread runs.</li>
  1733.      * </ul>
  1734.      *
  1735.      * @param timeBetweenEvictionRuns
  1736.      *            duration to sleep between evictor runs
  1737.      *
  1738.      * @see #getDurationBetweenEvictionRuns()
  1739.      * @since 2.10.0
  1740.      * @deprecated Use {@link #setDurationBetweenEvictionRuns(Duration)}.
  1741.      */
  1742.     @Deprecated
  1743.     public final void setTimeBetweenEvictionRuns(final Duration timeBetweenEvictionRuns) {
  1744.         this.durationBetweenEvictionRuns = PoolImplUtils.nonNull(timeBetweenEvictionRuns, BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS);
  1745.         startEvictor(this.durationBetweenEvictionRuns);
  1746.     }

  1747.     /**
  1748.      * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
  1749.      * <ul>
  1750.      * <li>When positive, the idle object evictor thread starts.</li>
  1751.      * <li>When non-positive, no idle object evictor thread runs.</li>
  1752.      * </ul>
  1753.      *
  1754.      * @param timeBetweenEvictionRunsMillis
  1755.      *            number of milliseconds to sleep between evictor runs
  1756.      *
  1757.      * @see #getDurationBetweenEvictionRuns()
  1758.      * @deprecated Use {@link #setDurationBetweenEvictionRuns(Duration)}.
  1759.      */
  1760.     @Deprecated
  1761.     public final void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
  1762.         setTimeBetweenEvictionRuns(Duration.ofMillis(timeBetweenEvictionRunsMillis));
  1763.     }

  1764.     /**
  1765.      * <p>Starts the evictor with the given delay. If there is an evictor
  1766.      * running when this method is called, it is stopped and replaced with a
  1767.      * new evictor with the specified delay.</p>
  1768.      *
  1769.      * <p>This method needs to be final, since it is called from a constructor.
  1770.      * See POOL-195.</p>
  1771.      *
  1772.      * @param delay time in milliseconds before start and between eviction runs
  1773.      */
  1774.     final void startEvictor(final Duration delay) {
  1775.         synchronized (evictionLock) {
  1776.             final boolean isPositiverDelay = PoolImplUtils.isPositive(delay);
  1777.             if (evictor == null) { // Starting evictor for the first time or after a cancel
  1778.                 if (isPositiverDelay) { // Starting new evictor
  1779.                     evictor = new Evictor();
  1780.                     EvictionTimer.schedule(evictor, delay, delay);
  1781.                 }
  1782.             } else if (isPositiverDelay) { // Stop or restart of existing evictor: Restart
  1783.                 synchronized (EvictionTimer.class) { // Ensure no cancel can happen between cancel / schedule calls
  1784.                     EvictionTimer.cancel(evictor, evictorShutdownTimeoutDuration, true);
  1785.                     evictor = null;
  1786.                     evictionIterator = null;
  1787.                     evictor = new Evictor();
  1788.                     EvictionTimer.schedule(evictor, delay, delay);
  1789.                 }
  1790.             } else { // Stopping evictor
  1791.                 EvictionTimer.cancel(evictor, evictorShutdownTimeoutDuration, false);
  1792.             }
  1793.         }
  1794.     }

  1795.     /**
  1796.      * Stops the evictor.
  1797.      */
  1798.     void stopEvictor() {
  1799.         startEvictor(Duration.ofMillis(-1L));
  1800.     }

  1801.     /**
  1802.      * Swallows an exception and notifies the configured listener for swallowed
  1803.      * exceptions queue.
  1804.      *
  1805.      * @param swallowException exception to be swallowed
  1806.      */
  1807.     final void swallowException(final Exception swallowException) {
  1808.         final SwallowedExceptionListener listener = getSwallowedExceptionListener();

  1809.         if (listener == null) {
  1810.             return;
  1811.         }

  1812.         try {
  1813.             listener.onSwallowException(swallowException);
  1814.         } catch (final VirtualMachineError e) {
  1815.             throw e;
  1816.         } catch (final Throwable ignored) {
  1817.             // Ignore. Enjoy the irony.
  1818.         }
  1819.     }

  1820.     @Override
  1821.     protected void toStringAppendFields(final StringBuilder builder) {
  1822.         builder.append("maxTotal=");
  1823.         builder.append(maxTotal);
  1824.         builder.append(", blockWhenExhausted=");
  1825.         builder.append(blockWhenExhausted);
  1826.         builder.append(", maxWaitDuration=");
  1827.         builder.append(maxWaitDuration);
  1828.         builder.append(", lifo=");
  1829.         builder.append(lifo);
  1830.         builder.append(", fairness=");
  1831.         builder.append(fairness);
  1832.         builder.append(", testOnCreate=");
  1833.         builder.append(testOnCreate);
  1834.         builder.append(", testOnBorrow=");
  1835.         builder.append(testOnBorrow);
  1836.         builder.append(", testOnReturn=");
  1837.         builder.append(testOnReturn);
  1838.         builder.append(", testWhileIdle=");
  1839.         builder.append(testWhileIdle);
  1840.         builder.append(", durationBetweenEvictionRuns=");
  1841.         builder.append(durationBetweenEvictionRuns);
  1842.         builder.append(", numTestsPerEvictionRun=");
  1843.         builder.append(numTestsPerEvictionRun);
  1844.         builder.append(", minEvictableIdleTimeDuration=");
  1845.         builder.append(minEvictableIdleDuration);
  1846.         builder.append(", softMinEvictableIdleTimeDuration=");
  1847.         builder.append(softMinEvictableIdleDuration);
  1848.         builder.append(", evictionPolicy=");
  1849.         builder.append(evictionPolicy);
  1850.         builder.append(", closeLock=");
  1851.         builder.append(closeLock);
  1852.         builder.append(", closed=");
  1853.         builder.append(closed);
  1854.         builder.append(", evictionLock=");
  1855.         builder.append(evictionLock);
  1856.         builder.append(", evictor=");
  1857.         builder.append(evictor);
  1858.         builder.append(", evictionIterator=");
  1859.         builder.append(evictionIterator);
  1860.         builder.append(", factoryClassLoader=");
  1861.         builder.append(factoryClassLoader);
  1862.         builder.append(", oname=");
  1863.         builder.append(objectName);
  1864.         builder.append(", creationStackTrace=");
  1865.         builder.append(creationStackTrace);
  1866.         builder.append(", borrowedCount=");
  1867.         builder.append(borrowedCount);
  1868.         builder.append(", returnedCount=");
  1869.         builder.append(returnedCount);
  1870.         builder.append(", createdCount=");
  1871.         builder.append(createdCount);
  1872.         builder.append(", destroyedCount=");
  1873.         builder.append(destroyedCount);
  1874.         builder.append(", destroyedByEvictorCount=");
  1875.         builder.append(destroyedByEvictorCount);
  1876.         builder.append(", destroyedByBorrowValidationCount=");
  1877.         builder.append(destroyedByBorrowValidationCount);
  1878.         builder.append(", activeTimes=");
  1879.         builder.append(activeTimes);
  1880.         builder.append(", idleTimes=");
  1881.         builder.append(idleTimes);
  1882.         builder.append(", waitTimes=");
  1883.         builder.append(waitTimes);
  1884.         builder.append(", maxBorrowWaitDuration=");
  1885.         builder.append(maxBorrowWaitDuration);
  1886.         builder.append(", swallowedExceptionListener=");
  1887.         builder.append(swallowedExceptionListener);
  1888.     }

  1889.     /**
  1890.      * Updates statistics after an object is borrowed from the pool.
  1891.      *
  1892.      * @param p object borrowed from the pool
  1893.      * @param waitDuration that the borrowing thread had to wait
  1894.      */
  1895.     final void updateStatsBorrow(final PooledObject<T> p, final Duration waitDuration) {
  1896.         borrowedCount.incrementAndGet();
  1897.         idleTimes.add(p.getIdleDuration());
  1898.         waitTimes.add(waitDuration);

  1899.         // lock-free optimistic-locking maximum
  1900.         Duration currentMaxDuration;
  1901.         do {
  1902.             currentMaxDuration = maxBorrowWaitDuration.get();
  1903.             if (currentMaxDuration.compareTo(waitDuration) >= 0) {
  1904.                 break;
  1905.             }
  1906.         } while (!maxBorrowWaitDuration.compareAndSet(currentMaxDuration, waitDuration));
  1907.     }

  1908.     /**
  1909.      * Updates statistics after an object is returned to the pool.
  1910.      *
  1911.      * @param activeTime the amount of time (in milliseconds) that the returning
  1912.      * object was checked out
  1913.      */
  1914.     final void updateStatsReturn(final Duration activeTime) {
  1915.         returnedCount.incrementAndGet();
  1916.         activeTimes.add(activeTime);
  1917.     }

  1918. }