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