1 package org.codehaus.plexus.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.ArrayList;
20
21
22
23
24
25
26
27
28 public class SweeperPool
29 {
30
31 private static final boolean DEBUG = false;
32
33
34 private transient Sweeper sweeper;
35
36
37 private transient int maxSize;
38
39
40 private transient int minSize;
41
42
43
44
45 private int triggerSize;
46
47
48 private ArrayList<Object> pooledObjects;
49
50
51 private boolean shuttingDown = false;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public SweeperPool( int maxSize, int minSize, int intialCapacity, int sweepInterval, int triggerSize )
70 {
71 super();
72 this.maxSize = saneConvert( maxSize );
73 this.minSize = saneConvert( minSize );
74 this.triggerSize = saneConvert( triggerSize );
75 pooledObjects = new ArrayList( intialCapacity );
76
77
78 if ( sweepInterval > 0 )
79 {
80 sweeper = new Sweeper( this, sweepInterval );
81 sweeper.start();
82 }
83 }
84
85 private int saneConvert( int value )
86 {
87 return Math.max( value, 0 );
88 }
89
90
91
92
93
94 public synchronized Object get()
95 {
96 if ( ( pooledObjects.size() == 0 ) || shuttingDown )
97 {
98 return null;
99 }
100 else
101 {
102 Object obj = pooledObjects.remove( 0 );
103 objectRetrieved( obj );
104
105
106 return obj;
107 }
108 }
109
110
111
112
113
114
115
116 public synchronized boolean put( Object obj )
117 {
118 objectAdded( obj );
119
120 if ( ( obj != null ) && ( pooledObjects.size() < maxSize ) && ( shuttingDown == false ) )
121 {
122 pooledObjects.add( obj );
123
124 return true;
125 }
126 else if ( obj != null )
127 {
128
129 objectDisposed( obj );
130 }
131
132 return false;
133 }
134
135
136
137
138
139
140 public synchronized int getSize()
141 {
142 return pooledObjects.size();
143 }
144
145
146
147
148 public void dispose()
149 {
150 shuttingDown = true;
151
152 if ( sweeper != null )
153 {
154 sweeper.stop();
155 try
156 {
157 sweeper.join();
158 }
159 catch ( InterruptedException e )
160 {
161 System.err.println( "Unexpected exception occurred: " );
162 e.printStackTrace();
163 }
164 }
165
166 synchronized ( this )
167 {
168
169
170 Object[] objects = pooledObjects.toArray();
171
172 for ( Object object : objects )
173 {
174 objectDisposed( object );
175 }
176
177 pooledObjects.clear();
178 }
179 }
180
181
182
183
184
185
186 boolean isDisposed()
187 {
188 if ( !shuttingDown )
189 {
190 return false;
191 }
192
193
194 if ( sweeper == null )
195 {
196 return true;
197 }
198
199 return sweeper.hasStopped();
200 }
201
202
203
204
205 public synchronized void trim()
206 {
207 if ( ( ( triggerSize > 0 ) && ( pooledObjects.size() >= triggerSize ) )
208 || ( ( maxSize > 0 ) && ( pooledObjects.size() >= maxSize ) ) )
209 {
210 while ( pooledObjects.size() > minSize )
211 {
212 objectDisposed( pooledObjects.remove( 0 ) );
213 }
214 }
215 }
216
217
218
219
220
221
222
223 public void objectDisposed( Object obj )
224 {
225 }
226
227
228
229
230
231
232 public void objectAdded( Object obj )
233 {
234 }
235
236
237
238
239
240
241
242 public void objectRetrieved( Object obj )
243 {
244 }
245
246
247
248
249
250
251 private static class Sweeper
252 implements Runnable
253 {
254 private final transient SweeperPool pool;
255
256 private transient boolean service = false;
257
258 private final transient int sweepInterval;
259
260 private transient Thread t = null;
261
262
263
264
265 public Sweeper( SweeperPool pool, int sweepInterval )
266 {
267 super();
268 this.sweepInterval = sweepInterval;
269 this.pool = pool;
270 }
271
272
273
274
275
276
277 @Override
278 public void run()
279 {
280 debug( "started" );
281
282 if ( sweepInterval > 0 )
283 {
284 synchronized ( this )
285 {
286 while ( service )
287 {
288 try
289 {
290
291
292 wait( sweepInterval * 1000 );
293 }
294 catch ( InterruptedException e )
295 {
296 }
297 runSweep();
298 }
299 }
300 }
301
302 debug( "stopped" );
303 }
304
305 public void start()
306 {
307 if ( !service )
308 {
309 service = true;
310 t = new Thread( this );
311 t.setName( "Sweeper" );
312 t.start();
313 }
314 }
315
316 public synchronized void stop()
317 {
318 service = false;
319 notifyAll();
320 }
321
322 void join()
323 throws InterruptedException
324 {
325 t.join();
326 }
327
328 boolean hasStopped()
329 {
330 return !service && !t.isAlive();
331 }
332
333 private final void debug( String msg )
334 {
335 if ( DEBUG )
336 {
337 System.err.println( this + ":" + msg );
338 }
339 }
340
341 private void runSweep()
342 {
343 debug( "runningSweep. time=" + System.currentTimeMillis() );
344 pool.trim();
345 }
346 }
347 }