/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.engine.util; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** * Generic object pool. * * @author Jerome Louvel * * @param <T> */ public abstract class Pool<T> { /** Store of reusable objects. */ private final Queue<T> store; /** * Default constructor. */ public Pool() { this.store = createStore(); } /** * Constructor. Pre-creates the minimum number of objects if needed using * the {@link #preCreate(int)} method. * * @param initialSize * The initial number of objects in the pool. */ public Pool(int initialSize) { this(); preCreate(initialSize); } /** * Checks in an object into the pool. * * @param object * The object to check in. */ public void checkin(T object) { if (object != null) { clear(object); this.store.offer(object); } } /** * Checks out an object from the pool. Creates a new one if the pool is * empty. * * @return An object from the pool. */ public T checkout() { T result; if ((result = this.store.poll()) == null) { result = createObject(); } return result; } /** * Clears the store of reusable objects. */ public void clear() { getStore().clear(); } /** * Clears the given object when it is checked in the pool. Does nothing by * default. * * @param object * The object to clear. */ protected void clear(T object) { } /** * Creates a new reusable object. * * @return A new reusable object. */ protected abstract T createObject(); /** * Creates the store of reusable objects. * * @return The store of reusable objects. */ protected Queue<T> createStore() { return new ConcurrentLinkedQueue<T>(); } /** * Returns the store containing the reusable objects. * * @return The store containing the reusable objects. */ protected Queue<T> getStore() { return store; } /** * Pre-creates the initial objects using the {@link #createObject()} method * and check them in the pool using the {@link #checkin(Object)} method. * * @param initialSize * The initial number of objects. */ public void preCreate(int initialSize) { for (int i = 0; i < initialSize; i++) { checkin(createObject()); } } }