KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > pool > SoftObjectPool


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 //NOTE: Tabs are used instead of spaces for indentation.
25
// Make sure that your editor does not replace tabs with spaces.
26
// Set the tab length using your favourite editor to your
27
// visual preference.
28

29 /*
30  * Filename: BoundedPool.java
31  *
32  * Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
33  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
34  * All rights reserved.
35  *
36  * This software is the confidential and proprietary information
37  * of iPlanet/Sun Microsystems, Inc. ("Confidential Information").
38  * You shall not disclose such Confidential Information and shall
39  * use it only in accordance with the terms of the license
40  * agreement you entered into with iPlanet/Sun Microsystems.
41  */

42  
43 /**
44  * <BR> <I>$Source: /cvs/glassfish/appserv-commons/src/java/com/sun/enterprise/util/pool/SoftObjectPool.java,v $</I>
45  * @author $Author: tcfujii $
46  * @version $Revision: 1.3 $ $Date: 2005/12/25 04:12:28 $
47  */

48  
49 package com.sun.enterprise.util.pool;
50
51 import java.util.List JavaDoc;
52 import java.util.Iterator JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.Collection JavaDoc;
55
56 import java.lang.ref.Reference JavaDoc;
57 import java.lang.ref.SoftReference JavaDoc;
58
59 import com.sun.enterprise.util.collection.DList;
60 import com.sun.enterprise.util.collection.DListNode;
61
62 import com.sun.enterprise.util.scheduler.PeriodicallyServicable;
63 import com.sun.enterprise.util.scheduler.PeriodicEventScheduler;
64
65 import com.sun.enterprise.util.ApproximateClock;
66 import com.sun.enterprise.util.collection.DListNode;
67 import com.sun.enterprise.util.collection.DListNodeFactory;
68
69 import com.sun.enterprise.util.collection.FastStack;
70 //Bug 4677074 begin
71
import java.util.logging.Logger JavaDoc;
72 import java.util.logging.Level JavaDoc;
73 import com.sun.logging.LogDomains;
74 //Bug 4677074 end
75

76
77 public class SoftObjectPool
78     extends com.sun.enterprise.util.pool.AbstractPool
79     implements PeriodicallyServicable
80 {
81 //Bug 4677074 begin
82
static Logger JavaDoc _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER);
83 //Bug 4677074 end
84
protected DList list;
85     protected int minSize;
86     protected int initialSize;
87     protected int maxLimit;
88     protected long maxIdleTime;
89     protected int maxStrongRefs;
90     
91     protected Boolean JavaDoc isBounded;
92     
93     /**
94      * Create an Unbounded pool.
95      * @param The ObjectFactory to create objects
96      * @param The minimum number of objects to be held in the pool (initial size)
97      * @param The initial size of the pool. If this is less than the minSize parameter then this is ignored.
98      * @param The maximum idle time after which the object may be removed from the pool.
99      * @param The pool limit (maximum number of objects in the pool).
100      */

101     public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize,
102                 long maxIdleTime, int maxStrongRefs) {
103         super();
104         super.factory = factory;
105         this.minSize = minSize;
106         this.initialSize = initialSize;
107         this.maxIdleTime = maxIdleTime;
108         this.maxStrongRefs = maxStrongRefs;
109         
110         setMaxLimit(-1);
111         
112         initPool();
113     }
114     
115     /**
116      * Create a Bounded pool.
117      * @param The ObjectFactory to create objects
118      * @param The minimum number of objects to be held in the pool (initial size)
119      * @param The pool limit (maximum number of objects in the pool).
120      * @param The maximum idle time after which the object may be removed from the pool.
121      * @param The initial size of the pool. If this is less than the minSize parameter then this is ignored.
122      */

123     public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize, int maxLimit,
124                     long maxIdleTime, int maxStrongRefs)
125     {
126         super();
127         super.factory = factory;
128         this.minSize = minSize;
129         this.maxIdleTime = maxIdleTime;
130         this.initialSize = initialSize;
131         this.maxStrongRefs = maxStrongRefs;
132         
133         setMaxLimit(maxLimit);
134         
135         initPool();
136     }
137     
138     public int getMaxLimit() {
139         return this.maxLimit;
140     }
141     
142     public void setMaxLimit(int limit) {
143         if ((limit <= 0) || (limit >= Integer.MAX_VALUE-1)) {
144             this.isBounded = null;
145         } else {
146             this.isBounded = new Boolean JavaDoc(true);
147             this.maxLimit = limit;
148         }
149     }
150         
151     
152     private void initPool() {
153         list = new DList();
154         
155         super.collection = list;
156         super.preload((minSize < initialSize) ? initialSize : minSize);
157         
158         scheduler.addTimeRepeatableTask(this, (int) maxIdleTime);
159     }
160     
161     /**
162      * Since this method would be called only if the pool is empty
163      */

164     protected boolean canCreate() {
165         return (isBounded == null) ? true : (createdCount < maxLimit);
166     }
167     
168     /**
169      * Notification when an object is put back into the pool (checkin).
170      * @param The object to be returned back to the pool.
171      * @return Any non null value can be returned to signal that the object
172      * was indeed added to the pool. This class always adds the object to the
173      * pool (at the end of the list), it returns non-null value.
174      * Subclasses can override this behaviour.
175      */

176     protected Object JavaDoc checkin(Object JavaDoc object) {
177         int size = list.size();
178         long now = _clock.getTime();
179
180         if (size < maxStrongRefs) {
181             list.addAsLastNode(new TimeStampedSoftDListNode(object, now, object));
182         } else {
183             list.addAsLastNode(new TimeStampedSoftDListNode(new SoftReference JavaDoc(object), now, null));
184         }
185
186         return this;
187     }
188                 
189     private Object JavaDoc obtainObject(Object JavaDoc param) {
190         SoftReference JavaDoc ref;
191         Object JavaDoc object = null;
192         int notifyCount = 0;
193         
194         for (int size = list.size(); size > 0; size--) {
195             TimeStampedSoftDListNode tsNode = (TimeStampedSoftDListNode) list.getDListNodeAt(0);
196             list.delink(tsNode);
197             
198             if (tsNode.isSoftRef == null) {
199                 ref = (SoftReference JavaDoc) tsNode.object;
200                 if ((object = ref.get()) != null) {
201                     break;
202                 } else {
203                     notifyCount++;
204                 }
205             } else {
206                 object = tsNode.object;
207                 break;
208             }
209         }
210             
211         if (object == null) {
212             try {
213                 object = factory.create(param);
214                 afterCreate(object);
215             } catch (PoolException poolEx) {
216                 
217             }
218         }
219         
220         super.createdCount -= notifyCount;
221         
222         if (notifyCount == 1) {
223             super.collection.notify();
224         } else if (notifyCount > 1) {
225             super.collection.notifyAll();
226         }
227         
228         return object;
229     }
230                 
231     /**
232      * Notification when an object is given out from the pool (checout).
233      * @return The object that has to be returned to the application. A null
234      * value must be returned if no object can be returned to the application. Since this
235      * class always returns the last node from the list, it returns non-null value.
236      * Subclasses can override this behaviour.
237      */

238     protected Object JavaDoc checkout(Object JavaDoc param) {
239         return obtainObject(param);
240     }
241     
242   
243     
244     //Methods required for periodically schedulable task
245

246     public void prolog() {
247     }
248     
249     public void service() {
250         int killedCount = 0;
251         
252         long now = _clock.getTime();
253         long allowed = now - maxIdleTime;
254         
255         TimeStampedSoftDListNode tsNode = null;
256         FastStack stack = new FastStack();
257         
258         synchronized (super.collection) {
259
260             Object JavaDoc done = null;
261             while (done == null) {
262                 tsNode = (TimeStampedSoftDListNode) list.getFirstDListNode();
263                 
264                 if (tsNode == null) { //Empty list
265
done = new Object JavaDoc();
266                 } else if (tsNode.timeStamp <= allowed) {
267                     //Need to destroy the contained object
268
list.delink(tsNode);
269                     stack.push(tsNode.object);
270                     killedCount++;
271                 } else {
272                     //This node is not old enough
273
done = new Object JavaDoc();
274                 }
275             } //End of for loop
276

277             super.createdCount -= killedCount;
278             
279             int deficit = list.size() - minSize;
280             super.preload(0 - deficit);
281             
282             if (killedCount == 0) {
283             } else if (killedCount == 1) {
284                 collection.notify();
285             } else {
286                 collection.notifyAll();
287             }
288             
289         } // end of synchronized
290

291         
292         //Now destroy all collected objects
293
while (! stack.isEmpty()) {
294             Object JavaDoc object = stack.pop();
295             beforeDestroy(object);
296             factory.destroy(object);
297         }
298         
299 //Bug 4677074 System.out.println("Leaving service after killing " + killedCount + " (idle) objects. Now size: " + list.size());
300
//Bug 4677074 begin
301
_logger.log(Level.FINE,"Leaving service after killing " + killedCount + " (idle) objects. Now size: " + list.size());
302 //Bug 4677074 end
303
}
304     
305     public void epilog() {
306     }
307     
308     /**
309     * Get the frequency (time interval) at which service() method will be invoked.
310     * @return time in milli seconds.
311     */

312     public long getFrequency() {
313         return this.maxIdleTime;
314     }
315     
316     /**
317     * Determine to execute the service method of this object even if it has
318     * missed the right schedule.
319     */

320     public boolean getExecuteIfMissed() {
321         return true;
322     }
323     
324     /**
325     * Determine to execute the service method of this object when the
326     * schedule is delayed by 'missedByMillis' milli seconds.
327     */

328     public boolean getExecutionTolerance(long missedByMillis) {
329         return true;
330     }
331     
332     /**
333     * Print an identification for the object.
334     */

335     public String JavaDoc toString() {
336         return "";
337     }
338     
339    //Some helper classes
340

341     class TimeStampedSoftDListNode
342         extends DListNode
343     {
344         long timeStamp;
345         Object JavaDoc isSoftRef;
346         
347         public TimeStampedSoftDListNode(Object JavaDoc object, long ts, Object JavaDoc isSoftRef) {
348             super(object);
349             this.timeStamp = ts;
350             this.isSoftRef = isSoftRef;
351                 
352 //Bug 4677074 System.out.println(this + ": created DListNode at: " + ts);
353
//Bug 4677074 begin
354
_logger.log(Level.FINE,this + ": created DListNode at: " + ts);
355 //Bug 4677074 end
356
}
357         
358         public String JavaDoc toString() {
359             return "TSDListNode: " + object + "; isSoftRef: " + isSoftRef;
360         }
361                     
362         
363     }
364     
365     
366 }
367
Popular Tags