001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.pool2; 018 019import java.io.Closeable; 020import java.util.Collection; 021import java.util.Iterator; 022import java.util.NoSuchElementException; 023 024/** 025 * A "keyed" pooling interface. 026 * <p> 027 * A keyed pool maintains a pool of instances for each key value. 028 * </p> 029 * <p> 030 * Example of use: 031 * </p> 032 * <pre style="border:solid thin; padding: 1ex;" 033 * > Object obj = <code style="color:#00C">null</code>; 034 * Object key = <code style="color:#C00">"Key"</code>; 035 * 036 * <code style="color:#00C">try</code> { 037 * obj = pool.borrowObject(key); 038 * <code style="color:#0C0">//...use the object...</code> 039 * } <code style="color:#00C">catch</code>(Exception e) { 040 * <code style="color:#0C0">// invalidate the object</code> 041 * pool.invalidateObject(key, obj); 042 * <code style="color:#0C0">// do not return the object to the pool twice</code> 043 * obj = <code style="color:#00C">null</code>; 044 * } <code style="color:#00C">finally</code> { 045 * <code style="color:#0C0">// make sure the object is returned to the pool</code> 046 * <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) { 047 * pool.returnObject(key, obj); 048 * } 049 * }</pre> 050 * <p> 051 * {@link KeyedObjectPool} implementations <i>may</i> choose to store at most 052 * one instance per key value, or may choose to maintain a pool of instances 053 * for each key (essentially creating a {@link java.util.Map Map} of 054 * {@link ObjectPool pools}). 055 * </p> 056 * <p> 057 * See {@link org.apache.commons.pool2.impl.GenericKeyedObjectPool 058 * GenericKeyedObjectPool} for an implementation. 059 * </p> 060 * 061 * @param <K> The type of keys maintained by this pool. 062 * @param <V> Type of element pooled in this pool. 063 * 064 * @see KeyedPooledObjectFactory 065 * @see ObjectPool 066 * @see org.apache.commons.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool 067 * 068 * @since 2.0 069 */ 070public interface KeyedObjectPool<K, V> extends Closeable { 071 072 /** 073 * Create an object using the {@link KeyedPooledObjectFactory factory} or 074 * other implementation dependent mechanism, passivate it, and then place it 075 * in the idle object pool. {@code addObject} is useful for 076 * "pre-loading" a pool with idle objects (Optional operation). 077 * 078 * @param key the key a new instance should be added to 079 * 080 * @throws Exception 081 * when {@link KeyedPooledObjectFactory#makeObject} fails. 082 * @throws IllegalStateException 083 * after {@link #close} has been called on this pool. 084 * @throws UnsupportedOperationException 085 * when this pool cannot add new idle objects. 086 */ 087 void addObject(K key) throws Exception, IllegalStateException, 088 UnsupportedOperationException; 089 090 /** 091 * Calls {@link KeyedObjectPool#addObject(Object)} with each 092 * key in {@code keys} for {@code count} number of times. This has 093 * the same effect as calling {@link #addObjects(Object, int)} 094 * for each key in the {@code keys} collection. 095 * 096 * @param keys 097 * {@link Collection} of keys to add objects for. 098 * @param count 099 * the number of idle objects to add for each {@code key}. 100 * @throws Exception 101 * when {@link KeyedObjectPool#addObject(Object)} fails. 102 * @throws IllegalArgumentException 103 * when {@code keyedPool}, {@code keys}, or any value 104 * in {@code keys} is {@code null}. 105 * @see #addObjects(Object, int) 106 */ 107 default void addObjects(final Collection<K> keys, final int count) throws Exception, IllegalArgumentException { 108 if (keys == null) { 109 throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEYS); 110 } 111 final Iterator<K> iter = keys.iterator(); 112 while (iter.hasNext()) { 113 addObjects(iter.next(), count); 114 } 115 } 116 117 /** 118 * Calls {@link KeyedObjectPool#addObject(Object)} 119 * {@code key} {@code count} number of times. 120 * 121 * @param key 122 * the key to add objects for. 123 * @param count 124 * the number of idle objects to add for {@code key}. 125 * @throws Exception 126 * when {@link KeyedObjectPool#addObject(Object)} fails. 127 * @throws IllegalArgumentException 128 * when {@code key} is {@code null}. 129 * @since 2.8.0 130 */ 131 default void addObjects(final K key, final int count) throws Exception, IllegalArgumentException { 132 if (key == null) { 133 throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEY); 134 } 135 for (int i = 0; i < count; i++) { 136 addObject(key); 137 } 138 } 139 140 /** 141 * Obtains an instance from this pool for the specified {@code key}. 142 * <p> 143 * Instances returned from this method will have been either newly created 144 * with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be 145 * a previously idle object and have been activated with 146 * {@link KeyedPooledObjectFactory#activateObject activateObject} and then 147 * (optionally) validated with 148 * {@link KeyedPooledObjectFactory#validateObject validateObject}. 149 * </p> 150 * <p> 151 * By contract, clients <strong>must</strong> return the borrowed object 152 * using {@link #returnObject returnObject}, 153 * {@link #invalidateObject invalidateObject}, or a related method as 154 * defined in an implementation or sub-interface, using a {@code key} 155 * that is {@link Object#equals equivalent} to the one used to borrow the 156 * instance in the first place. 157 * </p> 158 * <p> 159 * The behavior of this method when the pool has been exhausted is not 160 * strictly specified (although it may be specified by implementations). 161 * </p> 162 * 163 * @param key the key used to obtain the object 164 * 165 * @return an instance from this pool. 166 * 167 * @throws IllegalStateException 168 * after {@link #close close} has been called on this pool 169 * @throws Exception 170 * when {@link KeyedPooledObjectFactory#makeObject 171 * makeObject} throws an exception 172 * @throws NoSuchElementException 173 * when the pool is exhausted and cannot or will not return 174 * another instance 175 */ 176 V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException; 177 178 /** 179 * Clears the pool, removing all pooled instances (optional operation). 180 * 181 * @throws UnsupportedOperationException when this implementation doesn't 182 * support the operation 183 * 184 * @throws Exception if the pool cannot be cleared 185 */ 186 void clear() throws Exception, UnsupportedOperationException; 187 188 /** 189 * Clears the specified pool, removing all pooled instances corresponding to 190 * the given {@code key} (optional operation). 191 * 192 * @param key the key to clear 193 * 194 * @throws UnsupportedOperationException when this implementation doesn't 195 * support the operation 196 * 197 * @throws Exception if the key cannot be cleared 198 */ 199 void clear(K key) throws Exception, UnsupportedOperationException; 200 201 /** 202 * Close this pool, and free any resources associated with it. 203 * <p> 204 * Calling {@link #addObject addObject} or 205 * {@link #borrowObject borrowObject} after invoking this method on a pool 206 * will cause them to throw an {@link IllegalStateException}. 207 * </p> 208 * <p> 209 * Implementations should silently fail if not all resources can be freed. 210 * </p> 211 */ 212 @Override 213 void close(); 214 215 /** 216 * Returns the total number of instances currently borrowed from this pool but 217 * not yet returned. Returns a negative value if this information is not 218 * available. 219 * @return the total number of instances currently borrowed from this pool but 220 * not yet returned. 221 */ 222 int getNumActive(); 223 224 /** 225 * Returns the number of instances currently borrowed from but not yet 226 * returned to the pool corresponding to the given {@code key}. 227 * Returns a negative value if this information is not available. 228 * 229 * @param key the key to query 230 * @return the number of instances currently borrowed from but not yet 231 * returned to the pool corresponding to the given {@code key}. 232 */ 233 int getNumActive(K key); 234 235 /** 236 * Returns the total number of instances currently idle in this pool. 237 * Returns a negative value if this information is not available. 238 * @return the total number of instances currently idle in this pool. 239 */ 240 int getNumIdle(); 241 242 /** 243 * Returns the number of instances corresponding to the given 244 * {@code key} currently idle in this pool. Returns a negative value if 245 * this information is not available. 246 * 247 * @param key the key to query 248 * @return the number of instances corresponding to the given 249 * {@code key} currently idle in this pool. 250 */ 251 int getNumIdle(K key); 252 253 /** 254 * Invalidates an object from the pool. 255 * <p> 256 * By contract, {@code obj} <strong>must</strong> have been obtained 257 * using {@link #borrowObject borrowObject} or a related method as defined 258 * in an implementation or sub-interface using a {@code key} that is 259 * equivalent to the one used to borrow the {@code Object} in the first 260 * place. 261 * </p> 262 * <p> 263 * This method should be used when an object that has been borrowed is 264 * determined (due to an exception or other problem) to be invalid. 265 * </p> 266 * 267 * @param key the key used to obtain the object 268 * @param obj a {@link #borrowObject borrowed} instance to be returned. 269 * 270 * @throws Exception if the instance cannot be invalidated 271 */ 272 void invalidateObject(K key, V obj) throws Exception; 273 274 275 /** 276 * Invalidates an object from the pool, using the provided 277 * {@link DestroyMode}. 278 * <p> 279 * By contract, {@code obj} <strong>must</strong> have been obtained 280 * using {@link #borrowObject borrowObject} or a related method as defined 281 * in an implementation or sub-interface using a {@code key} that is 282 * equivalent to the one used to borrow the {@code Object} in the first 283 * place. 284 * </p> 285 * <p> 286 * This method should be used when an object that has been borrowed is 287 * determined (due to an exception or other problem) to be invalid. 288 * </p> 289 * 290 * @param key the key used to obtain the object 291 * @param obj a {@link #borrowObject borrowed} instance to be returned. 292 * @param mode destroy activation context provided to the factory 293 * 294 * @throws Exception if the instance cannot be invalidated 295 * @since 2.9.0 296 */ 297 default void invalidateObject(final K key, final V obj, final DestroyMode mode) throws Exception { 298 invalidateObject(key, obj); 299 } 300 301 /** 302 * Return an instance to the pool. By contract, {@code obj} 303 * <strong>must</strong> have been obtained using 304 * {@link #borrowObject borrowObject} or a related method as defined in an 305 * implementation or sub-interface using a {@code key} that is 306 * equivalent to the one used to borrow the instance in the first place. 307 * 308 * @param key the key used to obtain the object 309 * @param obj a {@link #borrowObject borrowed} instance to be returned. 310 * 311 * @throws IllegalStateException 312 * if an attempt is made to return an object to the pool that 313 * is in any state other than allocated (i.e. borrowed). 314 * Attempting to return an object more than once or attempting 315 * to return an object that was never borrowed from the pool 316 * will trigger this exception. 317 * 318 * @throws Exception if an instance cannot be returned to the pool 319 */ 320 void returnObject(K key, V obj) throws Exception; 321}