77 |
public final class ObjectPool |
public final class ObjectPool |
78 |
{ |
{ |
79 |
|
|
80 |
|
/** The maximum number of instances that we keep for each type. */ |
81 |
|
private static final int MAX_POOL_SIZE = 128; |
82 |
|
|
83 |
|
/** This flag turns on/off caching (for benchmarking purposes). */ |
84 |
|
private static final boolean IS_CACHING = true; |
85 |
|
|
86 |
/** The only instance of ObjectPool. */ |
/** The only instance of ObjectPool. */ |
87 |
private static ObjectPool instance; |
private static ObjectPool instance; |
88 |
|
|
93 |
* requested type is in the pool. |
* requested type is in the pool. |
94 |
*/ |
*/ |
95 |
private HashMap pool; |
private HashMap pool; |
96 |
|
|
97 |
|
/** |
98 |
|
* Collect some stats in this fields. TODO: Can be removed later. |
99 |
|
*/ |
100 |
|
int created = 0; |
101 |
|
int requested = 0; |
102 |
|
int returned = 0; |
103 |
|
int pooled = 0; |
104 |
|
|
105 |
/** |
/** |
106 |
* Creates a new instance of ObjectPool. This constructor is made private |
* Creates a new instance of ObjectPool. This constructor is made private |
116 |
* |
* |
117 |
* @return an ObjectPool instance ready for use |
* @return an ObjectPool instance ready for use |
118 |
*/ |
*/ |
119 |
public static ObjectPool getInstance() |
public static synchronized ObjectPool getInstance() |
120 |
{ |
{ |
121 |
if (instance == null) |
if (instance == null) |
122 |
instance = new ObjectPool(); |
instance = new ObjectPool(); |
137 |
*/ |
*/ |
138 |
public Object borrowObject(Class type) |
public Object borrowObject(Class type) |
139 |
{ |
{ |
140 |
|
// This is only here for benchmarking purposes. |
141 |
|
if (!IS_CACHING) |
142 |
|
return createObject(type); |
143 |
|
// Counts the requested objects. This is only here for benchmarking |
144 |
|
// purposes. |
145 |
|
requested++; |
146 |
|
if (requested % 10000 == 0) |
147 |
|
printStats(); |
148 |
|
|
149 |
|
|
150 |
Object object = null; |
Object object = null; |
151 |
Stack pooledInstances = (Stack) pool.get(type); |
Stack pooledInstances = null; |
152 |
|
synchronized (this) |
153 |
|
{ |
154 |
|
pooledInstances = (Stack) pool.get(type); |
155 |
|
} |
156 |
if (pooledInstances == null) |
if (pooledInstances == null) |
157 |
object = createObject(type); |
object = createObject(type); |
158 |
else |
else |
159 |
if (pooledInstances.size() == 0) |
if (pooledInstances.size() == 0) |
160 |
object = createObject(type); |
object = createObject(type); |
161 |
else |
else |
162 |
object = pooledInstances.pop(); |
synchronized (this) |
163 |
|
{ |
164 |
|
object = pooledInstances.pop(); |
165 |
|
} |
166 |
return object; |
return object; |
167 |
} |
} |
168 |
|
|
173 |
*/ |
*/ |
174 |
public void returnObject(Object object) |
public void returnObject(Object object) |
175 |
{ |
{ |
176 |
|
// This is only here for benchmarking purposes. |
177 |
|
if (!IS_CACHING) |
178 |
|
return; |
179 |
|
// Count the returned objects. This is only here for benchmarking purposes. |
180 |
|
returned++; |
181 |
|
|
182 |
Class type = object.getClass(); |
Class type = object.getClass(); |
183 |
Stack pooledInstances = (Stack) pool.get(type); |
Stack pooledInstances = null; |
184 |
|
synchronized (this) |
185 |
|
{ |
186 |
|
pooledInstances = (Stack) pool.get(type); |
187 |
|
} |
188 |
if (pooledInstances == null) |
if (pooledInstances == null) |
189 |
{ |
{ |
190 |
pooledInstances = new Stack(); |
pooledInstances = new Stack(); |
|
pool.put(type, pooledInstances); |
|
191 |
} |
} |
192 |
pooledInstances.push(object); |
if (pooledInstances.size() < MAX_POOL_SIZE) |
193 |
|
synchronized (this) |
194 |
|
{ |
195 |
|
pool.put(type, pooledInstances); |
196 |
|
|
197 |
|
// Count the objects that are actually pooled. This is only |
198 |
|
// here for benchmarking purposes. |
199 |
|
pooled++; |
200 |
|
} |
201 |
|
|
202 |
|
synchronized (this) |
203 |
|
{ |
204 |
|
pooledInstances.push(object); |
205 |
|
} |
206 |
} |
} |
207 |
|
|
208 |
/** |
/** |
215 |
*/ |
*/ |
216 |
private Object createObject(Class type) |
private Object createObject(Class type) |
217 |
{ |
{ |
218 |
|
// Counts the objects that are created here. This is only here for |
219 |
|
// benchmarking purposes. |
220 |
|
created++; |
221 |
|
|
222 |
|
|
223 |
Object object = null; |
Object object = null; |
224 |
try |
try |
225 |
{ |
{ |
235 |
} |
} |
236 |
return object; |
return object; |
237 |
} |
} |
238 |
|
|
239 |
|
/** |
240 |
|
* This method prints out some stats about the object pool. This gives |
241 |
|
* an indication on how efficiently the pool is used. |
242 |
|
*/ |
243 |
|
void printStats() |
244 |
|
{ |
245 |
|
System.err.println("Requested Objects: " + requested); |
246 |
|
System.err.println("Returned Objects: " + returned); |
247 |
|
System.err.println("Created Objects: " + created); |
248 |
|
System.err.println("Pooled Objects: " + pooled); |
249 |
|
} |
250 |
} |
} |