1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.util; 18 19 import android.annotation.UnsupportedAppUsage; 20 21 /** 22 * Helper class for crating pools of objects. An example use looks like this: 23 * <pre> 24 * public class MyPooledClass { 25 * 26 * private static final SynchronizedPool<MyPooledClass> sPool = 27 * new SynchronizedPool<MyPooledClass>(10); 28 * 29 * public static MyPooledClass obtain() { 30 * MyPooledClass instance = sPool.acquire(); 31 * return (instance != null) ? instance : new MyPooledClass(); 32 * } 33 * 34 * public void recycle() { 35 * // Clear state if needed. 36 * sPool.release(this); 37 * } 38 * 39 * . . . 40 * } 41 * </pre> 42 * 43 * @hide 44 */ 45 public final class Pools { 46 47 /** 48 * Interface for managing a pool of objects. 49 * 50 * @param <T> The pooled type. 51 */ 52 public static interface Pool<T> { 53 54 /** 55 * @return An instance from the pool if such, null otherwise. 56 */ 57 @UnsupportedAppUsage acquire()58 public T acquire(); 59 60 /** 61 * Release an instance to the pool. 62 * 63 * @param instance The instance to release. 64 * @return Whether the instance was put in the pool. 65 * 66 * @throws IllegalStateException If the instance is already in the pool. 67 */ 68 @UnsupportedAppUsage release(T instance)69 public boolean release(T instance); 70 } 71 Pools()72 private Pools() { 73 /* do nothing - hiding constructor */ 74 } 75 76 /** 77 * Simple (non-synchronized) pool of objects. 78 * 79 * @param <T> The pooled type. 80 */ 81 public static class SimplePool<T> implements Pool<T> { 82 @UnsupportedAppUsage 83 private final Object[] mPool; 84 85 private int mPoolSize; 86 87 /** 88 * Creates a new instance. 89 * 90 * @param maxPoolSize The max pool size. 91 * 92 * @throws IllegalArgumentException If the max pool size is less than zero. 93 */ 94 @UnsupportedAppUsage SimplePool(int maxPoolSize)95 public SimplePool(int maxPoolSize) { 96 if (maxPoolSize <= 0) { 97 throw new IllegalArgumentException("The max pool size must be > 0"); 98 } 99 mPool = new Object[maxPoolSize]; 100 } 101 102 @Override 103 @SuppressWarnings("unchecked") 104 @UnsupportedAppUsage acquire()105 public T acquire() { 106 if (mPoolSize > 0) { 107 final int lastPooledIndex = mPoolSize - 1; 108 T instance = (T) mPool[lastPooledIndex]; 109 mPool[lastPooledIndex] = null; 110 mPoolSize--; 111 return instance; 112 } 113 return null; 114 } 115 116 @Override 117 @UnsupportedAppUsage release(T instance)118 public boolean release(T instance) { 119 if (isInPool(instance)) { 120 throw new IllegalStateException("Already in the pool!"); 121 } 122 if (mPoolSize < mPool.length) { 123 mPool[mPoolSize] = instance; 124 mPoolSize++; 125 return true; 126 } 127 return false; 128 } 129 isInPool(T instance)130 private boolean isInPool(T instance) { 131 for (int i = 0; i < mPoolSize; i++) { 132 if (mPool[i] == instance) { 133 return true; 134 } 135 } 136 return false; 137 } 138 } 139 140 /** 141 * Synchronized pool of objects. 142 * 143 * @param <T> The pooled type. 144 */ 145 public static class SynchronizedPool<T> extends SimplePool<T> { 146 private final Object mLock; 147 148 /** 149 * Creates a new instance. 150 * 151 * @param maxPoolSize The max pool size. 152 * @param lock an optional custom object to synchronize on 153 * 154 * @throws IllegalArgumentException If the max pool size is less than zero. 155 */ SynchronizedPool(int maxPoolSize, Object lock)156 public SynchronizedPool(int maxPoolSize, Object lock) { 157 super(maxPoolSize); 158 mLock = lock; 159 } 160 161 /** @see #SynchronizedPool(int, Object) */ 162 @UnsupportedAppUsage SynchronizedPool(int maxPoolSize)163 public SynchronizedPool(int maxPoolSize) { 164 this(maxPoolSize, new Object()); 165 } 166 167 @Override 168 @UnsupportedAppUsage acquire()169 public T acquire() { 170 synchronized (mLock) { 171 return super.acquire(); 172 } 173 } 174 175 @Override 176 @UnsupportedAppUsage release(T element)177 public boolean release(T element) { 178 synchronized (mLock) { 179 return super.release(element); 180 } 181 } 182 } 183 } 184