KeyedObjectPool.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;

  18. import java.io.Closeable;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.List;
  22. import java.util.NoSuchElementException;

  23. /**
  24.  * A "keyed" pooling interface.
  25.  * <p>
  26.  * A keyed pool maintains a pool of instances for each key value.
  27.  * </p>
  28.  * <p>
  29.  * Example of use:
  30.  * </p>
  31.  * <pre style="border:solid thin; padding: 1ex;"
  32.  * > Object obj = <code style="color:#00C">null</code>;
  33.  * Object key = <code style="color:#C00">"Key"</code>;
  34.  *
  35.  * <code style="color:#00C">try</code> {
  36.  *     obj = pool.borrowObject(key);
  37.  *     <code style="color:#0C0">//...use the object...</code>
  38.  * } <code style="color:#00C">catch</code> (Exception e) {
  39.  *     <code style="color:#0C0">// invalidate the object</code>
  40.  *     pool.invalidateObject(key, obj);
  41.  *     <code style="color:#0C0">// do not return the object to the pool twice</code>
  42.  *     obj = <code style="color:#00C">null</code>;
  43.  * } <code style="color:#00C">finally</code> {
  44.  *     <code style="color:#0C0">// make sure the object is returned to the pool</code>
  45.  *     <code style="color:#00C">if</code> (<code style="color:#00C">null</code> != obj) {
  46.  *         pool.returnObject(key, obj);
  47.  *     }
  48.  * }</pre>
  49.  * <p>
  50.  * {@link KeyedObjectPool} implementations <em>may</em> choose to store at most
  51.  * one instance per key value, or may choose to maintain a pool of instances
  52.  * for each key (essentially creating a {@link java.util.Map Map} of
  53.  * {@link ObjectPool pools}).
  54.  * </p>
  55.  * <p>
  56.  * See {@link org.apache.commons.pool2.impl.GenericKeyedObjectPool
  57.  * GenericKeyedObjectPool} for an implementation.
  58.  * </p>
  59.  *
  60.  * @param <K> The type of keys maintained by this pool.
  61.  * @param <V> Type of element pooled in this pool.
  62.  *
  63.  *
  64.  * @see KeyedPooledObjectFactory
  65.  * @see ObjectPool
  66.  * @see org.apache.commons.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool
  67.  * @since 2.0
  68.  */
  69. public interface KeyedObjectPool<K, V> extends Closeable {

  70.     /**
  71.      * Creates an object using the {@link KeyedPooledObjectFactory factory} or
  72.      * other implementation dependent mechanism, passivate it, and then place it
  73.      * in the idle object pool. {@code addObject} is useful for
  74.      * "pre-loading" a pool with idle objects (Optional operation).
  75.      *
  76.      * @param key the key a new instance should be added to
  77.      * @throws Exception
  78.      *              when {@link KeyedPooledObjectFactory#makeObject} fails.
  79.      * @throws IllegalStateException
  80.      *              after {@link #close} has been called on this pool.
  81.      * @throws UnsupportedOperationException
  82.      *              when this pool cannot add new idle objects.
  83.      */
  84.     void addObject(K key) throws Exception;

  85.     /**
  86.      * Calls {@link KeyedObjectPool#addObject(Object)} with each
  87.      * key in {@code keys} for {@code count} number of times. This has
  88.      * the same effect as calling {@link #addObjects(Object, int)}
  89.      * for each key in the {@code keys} collection.
  90.      *
  91.      * @param keys
  92.      *            {@link Collection} of keys to add objects for.
  93.      * @param count
  94.      *            the number of idle objects to add for each {@code key}.
  95.      * @throws Exception
  96.      *             when {@link KeyedObjectPool#addObject(Object)} fails.
  97.      * @throws IllegalArgumentException
  98.      *             when {@code keyedPool}, {@code keys}, or any value
  99.      *             in {@code keys} is {@code null}.
  100.      * @see #addObjects(Object, int)
  101.      */
  102.     default void addObjects(final Collection<K> keys, final int count) throws Exception {
  103.         if (keys == null) {
  104.             throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEYS);
  105.         }
  106.         for (final K key : keys) {
  107.             addObjects(key, count);
  108.         }
  109.     }

  110.     /**
  111.      * Calls {@link KeyedObjectPool#addObject(Object)}
  112.      * {@code key} {@code count} number of times.
  113.      *
  114.      * @param key
  115.      *            the key to add objects for.
  116.      * @param count
  117.      *            the number of idle objects to add for {@code key}.
  118.      * @throws Exception
  119.      *             when {@link KeyedObjectPool#addObject(Object)} fails.
  120.      * @throws IllegalArgumentException
  121.      *             when {@code key} is {@code null}.
  122.      * @since 2.8.0
  123.      */
  124.     default void addObjects(final K key, final int count) throws Exception {
  125.         if (key == null) {
  126.             throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEY);
  127.         }
  128.         for (int i = 0; i < count; i++) {
  129.             addObject(key);
  130.         }
  131.     }

  132.     /**
  133.      * Borrows an instance from this pool for the specified {@code key}.
  134.      * <p>
  135.      * Instances returned from this method will have been either newly created
  136.      * with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be
  137.      * a previously idle object and have been activated with
  138.      * {@link KeyedPooledObjectFactory#activateObject activateObject} and then
  139.      * (optionally) validated with
  140.      * {@link KeyedPooledObjectFactory#validateObject validateObject}.
  141.      * </p>
  142.      * <p>
  143.      * By contract, clients <strong>must</strong> return the borrowed object
  144.      * using {@link #returnObject returnObject},
  145.      * {@link #invalidateObject invalidateObject}, or a related method as
  146.      * defined in an implementation or sub-interface, using a {@code key}
  147.      * that is {@link Object#equals equivalent} to the one used to borrow the
  148.      * instance in the first place.
  149.      * </p>
  150.      * <p>
  151.      * The behavior of this method when the pool has been exhausted is not
  152.      * strictly specified (although it may be specified by implementations).
  153.      * </p>
  154.      *
  155.      * @param key the key used to obtain the object
  156.      * @return an instance from this pool.
  157.      * @throws IllegalStateException
  158.      *              after {@link #close close} has been called on this pool
  159.      * @throws Exception
  160.      *              when {@link KeyedPooledObjectFactory#makeObject
  161.      *              makeObject} throws an exception
  162.      * @throws NoSuchElementException
  163.      *              when the pool is exhausted and cannot or will not return
  164.      *              another instance
  165.      */
  166.     V borrowObject(K key) throws Exception;

  167.     /**
  168.      * Clears the pool, removing all pooled instances (optional operation).
  169.      *
  170.      * @throws UnsupportedOperationException when this implementation doesn't
  171.      *                                       support the operation
  172.      *
  173.      * @throws Exception if the pool cannot be cleared
  174.      */
  175.     void clear() throws Exception;

  176.     /**
  177.      * Clears the specified pool, removing all pooled instances corresponding to
  178.      * the given {@code key} (optional operation).
  179.      *
  180.      * @param key the key to clear
  181.      * @throws UnsupportedOperationException when this implementation doesn't
  182.      *                                       support the operation
  183.      *
  184.      * @throws Exception if the key cannot be cleared
  185.      */
  186.     void clear(K key) throws Exception;

  187.     /**
  188.      * Closes this pool, and free any resources associated with it.
  189.      * <p>
  190.      * Calling {@link #addObject addObject} or
  191.      * {@link #borrowObject borrowObject} after invoking this method on a pool
  192.      * will cause them to throw an {@link IllegalStateException}.
  193.      * </p>
  194.      * <p>
  195.      * Implementations should silently fail if not all resources can be freed.
  196.      * </p>
  197.      */
  198.     @Override
  199.     void close();

  200.     /**
  201.      * Gets a copy of the pool key list.
  202.      * <p>
  203.      * Note: The default implementation returns an empty list.
  204.      * Implementations should override this method.
  205.      * </p>
  206.      *
  207.      * @return a copy of the pool key list.
  208.      * @since 2.12.0
  209.      */
  210.     default List<K> getKeys() {
  211.         return Collections.emptyList();
  212.     }

  213.     /**
  214.      * Gets the total number of instances currently borrowed from this pool but
  215.      * not yet returned. Returns a negative value if this information is not
  216.      * available.
  217.      * @return the total number of instances currently borrowed from this pool but
  218.      * not yet returned.
  219.      */
  220.     int getNumActive();

  221.     /**
  222.      * Gets the number of instances currently borrowed from but not yet
  223.      * returned to the pool corresponding to the given {@code key}.
  224.      * Returns a negative value if this information is not available.
  225.      *
  226.      * @param key the key to query
  227.      * @return the number of instances currently borrowed from but not yet
  228.      * returned to the pool corresponding to the given {@code key}.
  229.      */
  230.     int getNumActive(K key);

  231.     /**
  232.      * Gets the total number of instances currently idle in this pool.
  233.      * Returns a negative value if this information is not available.
  234.      * @return the total number of instances currently idle in this pool.
  235.      */
  236.     int getNumIdle();

  237.     /**
  238.      * Gets the number of instances corresponding to the given
  239.      * {@code key} currently idle in this pool. Returns a negative value if
  240.      * this information is not available.
  241.      *
  242.      * @param key the key to query
  243.      * @return the number of instances corresponding to the given
  244.      * {@code key} currently idle in this pool.
  245.      */
  246.     int getNumIdle(K key);

  247.     /**
  248.      * Invalidates an object from the pool.
  249.      * <p>
  250.      * By contract, {@code obj} <strong>must</strong> have been obtained
  251.      * using {@link #borrowObject borrowObject} or a related method as defined
  252.      * in an implementation or sub-interface using a {@code key} that is
  253.      * equivalent to the one used to borrow the {@code Object} in the first
  254.      * place.
  255.      * </p>
  256.      * <p>
  257.      * This method should be used when an object that has been borrowed is
  258.      * determined (due to an exception or other problem) to be invalid.
  259.      * </p>
  260.      *
  261.      * @param key the key used to obtain the object
  262.      * @param obj a {@link #borrowObject borrowed} instance to be returned.
  263.      * @throws Exception if the instance cannot be invalidated
  264.      */
  265.     void invalidateObject(K key, V obj) throws Exception;

  266.     /**
  267.      * Invalidates an object from the pool, using the provided
  268.      * {@link DestroyMode}.
  269.      * <p>
  270.      * By contract, {@code obj} <strong>must</strong> have been obtained
  271.      * using {@link #borrowObject borrowObject} or a related method as defined
  272.      * in an implementation or sub-interface using a {@code key} that is
  273.      * equivalent to the one used to borrow the {@code Object} in the first
  274.      * place.
  275.      * </p>
  276.      * <p>
  277.      * This method should be used when an object that has been borrowed is
  278.      * determined (due to an exception or other problem) to be invalid.
  279.      * </p>
  280.      *
  281.      * @param key the key used to obtain the object
  282.      * @param obj a {@link #borrowObject borrowed} instance to be returned.
  283.      * @param destroyMode destroy activation context provided to the factory
  284.      * @throws Exception if the instance cannot be invalidated
  285.      * @since 2.9.0
  286.      */
  287.     default void invalidateObject(final K key, final V obj, final DestroyMode destroyMode) throws Exception {
  288.         invalidateObject(key, obj);
  289.     }

  290.     /**
  291.      * Return an instance to the pool. By contract, {@code obj}
  292.      * <strong>must</strong> have been obtained using
  293.      * {@link #borrowObject borrowObject} or a related method as defined in an
  294.      * implementation or sub-interface using a {@code key} that is
  295.      * equivalent to the one used to borrow the instance in the first place.
  296.      *
  297.      * @param key the key used to obtain the object
  298.      * @param obj a {@link #borrowObject borrowed} instance to be returned.
  299.      * @throws IllegalStateException
  300.      *              if an attempt is made to return an object to the pool that
  301.      *              is in any state other than allocated (i.e. borrowed).
  302.      *              Attempting to return an object more than once or attempting
  303.      *              to return an object that was never borrowed from the pool
  304.      *              will trigger this exception.
  305.      *
  306.      * @throws Exception if an instance cannot be returned to the pool
  307.      */
  308.     void returnObject(K key, V obj) throws Exception;
  309. }