KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > net > Pool


1 package org.sapia.ubik.net;
2
3 import java.util.*;
4
5
6 /**
7  * Implements a basic object pool. Pooled objects must be returned to the pool
8  * once done with.
9  *
10  * @author Yanick Duchesne
11  * <dl>
12  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
13  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
14  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
15  * </dl>
16  */

17 public abstract class Pool {
18   public static final long NO_TIME_OUT = -1;
19   public static final int NO_MAX = 0;
20   protected List _objects = Collections.synchronizedList(new ArrayList(
21         50));
22   protected int _maxSize = NO_MAX;
23   protected int _currentCount;
24   protected long _lastUsageTime = System.currentTimeMillis();
25
26   public Pool() {
27   }
28
29   public Pool(int maxSize) {
30     _maxSize = maxSize;
31   }
32
33   /**
34    * Acquires an object from the pool; waits indefinitely that an
35    * object becomes available if the pool is empty and its maximum
36    * created object count has been reach. If the maximum number of objects has
37    * not been reached, or if the pool has no such maximum defined, an object
38    * is internally created and immediately returned.
39    *
40    * @return an <code>Object</code>
41    * @throws an <code>Exception</code> if a problem occurs acquiring the object.
42    */

43   public synchronized Object JavaDoc acquire() throws InterruptedException JavaDoc, Exception JavaDoc {
44     return acquire(NO_TIME_OUT);
45   }
46
47   /**
48    * Acquires an object from this pool; if the pool is empty and its maximum
49    * created object count has been reach, this method waits for the specified
50    * timeout that an object becomes ready. If the maximum number of objects has
51    * not been reached, or if the pool has no such maximum defined, an object
52    * is internally created and immediately returned.
53    *
54    * @param timeout a timeout to wait for until an object becomes available (in millis).
55    * @return an <code>Object</code>
56    * @throws NoObjectAvailableException if an object could not be acquired within
57    * the specified amount of time.
58    * @throws Exception if a problem occurs creating the object.
59    */

60   public synchronized Object JavaDoc acquire(long timeout)
61     throws InterruptedException JavaDoc, NoObjectAvailableException, Exception JavaDoc {
62     _lastUsageTime = System.currentTimeMillis();
63
64     Object JavaDoc obj;
65
66     if (_objects.size() == 0) {
67       if (_maxSize <= NO_MAX) {
68         obj = newObject();
69       } else {
70         long start = System.currentTimeMillis();
71
72         while (_objects.size() == 0) {
73           if (timeout > 0) {
74             wait(timeout);
75
76             if ((System.currentTimeMillis() - start) > timeout) {
77               break;
78             }
79           } else {
80             if (_currentCount > _maxSize) {
81               wait();
82             } else {
83               break;
84             }
85           }
86         }
87
88         if (_objects.size() == 0) {
89           if (_currentCount >= _maxSize) {
90             throw new NoObjectAvailableException();
91           } else {
92             obj = newObject();
93           }
94         } else {
95           obj = _objects.remove(0);
96         }
97       }
98     } else {
99       obj = _objects.remove(0);
100     }
101
102     return onAcquire(obj);
103   }
104
105   protected Object JavaDoc onAcquire(Object JavaDoc o) throws Exception JavaDoc {
106     return o;
107   }
108
109   protected void onRelease(Object JavaDoc o) {
110   }
111
112   /**
113    * Releases the given object to the given pool.
114    *
115    * @param obj an <code>Object</code> to put back into
116    * the pool.
117    */

118   public synchronized void release(Object JavaDoc obj) {
119     _objects.add(obj);
120     onRelease(obj);
121     notify();
122   }
123
124   /**
125    * Returns the time an object was last acquired from this
126    * pool.
127    */

128   public long getLastUsageTime() {
129     return _lastUsageTime;
130   }
131
132   /**
133    * Returns the number of objects that have been created by this
134    * pool so far.
135    *
136    * @return the number of created object.
137    */

138   public int getCreatedCount() {
139     return _currentCount;
140   }
141
142   /**
143    * Returns the number of objects currently in the pool.
144    *
145    * @return the number of objects currently in the pool.
146    */

147   public int size() {
148     return _objects.size();
149   }
150
151   /**
152    * Shrinks the pool to the specified size, or until the pool is
153    * empty. This method internally calls the <code>cleanup()</code>
154    * method for each object in the pool, so that the cleaned objects
155    * are properly disposed of.
156    *
157    * @param size the size to which to clean the pool.
158    * @see #cleanup(Object)
159    */

160   public synchronized void shrinkTo(int size) {
161     while ((_objects.size() > size) && (_objects.size() > 0)) {
162       _currentCount--;
163
164       if (_currentCount < 0) {
165         _currentCount = 0;
166       }
167
168       cleanup(_objects.remove(0));
169     }
170   }
171   
172   /***
173    * Fills the pool up to the given size, or up to this pool's
174    * specified maximum size (if the latter was specified).
175    *
176    * @param toSize the size up to which this pool should be filled.
177    */

178   public synchronized void fill(int toSize) throws Exception JavaDoc {
179     for (int i = 0; i < toSize; i++) {
180       if ((_maxSize > NO_MAX) && (_objects.size() >= _maxSize)) {
181         break;
182       }
183
184       _objects.add(newObject());
185     }
186   }
187
188   /**
189    * This method attempts to acquire an object from this pool. If
190    * this pool is currently empty and its maximum number of created
191    * objects has been reached, then <code>null</code>. If this pool
192    * is currently empty but no maximum number of created objects has been
193    * defined (at construction time), then a new object will be created and
194    * returned.
195    *
196    * @return an <code>Object</code>, or <code>null</code> if the pool is currently empty
197    * and has reached the maximum number of objects it can create.
198    * @throws Exception if no object could be acquired/created.
199    */

200   public synchronized Object JavaDoc acquireCreate() throws Exception JavaDoc{
201     if(_objects.size() == 0){
202       if(getCreatedCount() >= _maxSize && _maxSize > NO_MAX){
203         return null;
204       }
205       else{
206         return acquire();
207       }
208     }
209     else{
210       return acquire();
211     }
212   }
213
214   /*////////////////////////////////////////////////////////////////////
215                            RESTRICTED METHODS
216   ////////////////////////////////////////////////////////////////////*/

217
218   /**
219    * This template method should be overridden by inheriting classes to
220    * provide object instances that will be pooled.
221    *
222    * @return an <code>Object</code> to pool.
223    * @throws Exception if an error occurs while creating the object to be
224    * returned.
225    */

226   protected abstract Object JavaDoc doNewObject() throws Exception JavaDoc;
227
228   /**
229    * Inheriting classes should override this method to implement proper
230    * cleanup behavior for pooled objects. This method has an empty
231    * implementation by default.
232    *
233    * @see #shrinkTo(int)
234    */

235   protected void cleanup(Object JavaDoc pooled) {
236   }
237
238   private Object JavaDoc newObject() throws Exception JavaDoc {
239     Object JavaDoc toReturn = doNewObject();
240     _currentCount++;
241
242     return toReturn;
243   }
244 }
245
Popular Tags