• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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