KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > pool > impl > StackObjectPool


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.pool.impl;
18
19 import java.util.Iterator JavaDoc;
20 import java.util.NoSuchElementException JavaDoc;
21 import java.util.Stack JavaDoc;
22
23 import org.apache.commons.pool.BaseObjectPool;
24 import org.apache.commons.pool.ObjectPool;
25 import org.apache.commons.pool.PoolableObjectFactory;
26
27 /**
28  * A simple, {@link java.util.Stack Stack}-based {@link ObjectPool} implementation.
29  * <p>
30  * Given a {@link PoolableObjectFactory}, this class will maintain
31  * a simple pool of instances. A finite number of "sleeping"
32  * or idle instances is enforced, but when the pool is
33  * empty, new instances are created to support the new load.
34  * Hence this class places no limit on the number of "active"
35  * instances created by the pool, but is quite useful for
36  * re-using <tt>Object</tt>s without introducing
37  * artificial limits.
38  *
39  * @author Rodney Waldhoff
40  * @author Dirk Verbeeck
41  * @version $Revision$ $Date: 2005-05-16 04:18:31 -0700 (Mon, 16 May 2005) $
42  */

43 public class StackObjectPool extends BaseObjectPool implements ObjectPool {
44     /**
45      * Create a new pool using
46      * no factory. Clients must first populate the pool
47      * using {@link #returnObject(java.lang.Object)}
48      * before they can be {@link #borrowObject borrowed}.
49      */

50     public StackObjectPool() {
51         this((PoolableObjectFactory)null,DEFAULT_MAX_SLEEPING,DEFAULT_INIT_SLEEPING_CAPACITY);
52     }
53
54     /**
55      * Create a new pool using
56      * no factory. Clients must first populate the pool
57      * using {@link #returnObject(java.lang.Object)}
58      * before they can be {@link #borrowObject borrowed}.
59      *
60      * @param maxIdle cap on the number of "sleeping" instances in the pool
61      */

62     public StackObjectPool(int maxIdle) {
63         this((PoolableObjectFactory)null,maxIdle,DEFAULT_INIT_SLEEPING_CAPACITY);
64     }
65
66     /**
67      * Create a new pool using
68      * no factory. Clients must first populate the pool
69      * using {@link #returnObject(java.lang.Object)}
70      * before they can be {@link #borrowObject borrowed}.
71      *
72      * @param maxIdle cap on the number of "sleeping" instances in the pool
73      * @param initIdleCapacity initial size of the pool (this specifies the size of the container,
74      * it does not cause the pool to be pre-populated.)
75      */

76     public StackObjectPool(int maxIdle, int initIdleCapacity) {
77         this((PoolableObjectFactory)null,maxIdle,initIdleCapacity);
78     }
79
80     /**
81      * Create a new <tt>StackObjectPool</tt> using
82      * the specified <i>factory</i> to create new instances.
83      *
84      * @param factory the {@link PoolableObjectFactory} used to populate the pool
85      */

86     public StackObjectPool(PoolableObjectFactory factory) {
87         this(factory,DEFAULT_MAX_SLEEPING,DEFAULT_INIT_SLEEPING_CAPACITY);
88     }
89
90     /**
91      * Create a new <tt>SimpleObjectPool</tt> using
92      * the specified <i>factory</i> to create new instances,
93      * capping the number of "sleeping" instances to <i>max</i>.
94      *
95      * @param factory the {@link PoolableObjectFactory} used to populate the pool
96      * @param maxIdle cap on the number of "sleeping" instances in the pool
97      */

98     public StackObjectPool(PoolableObjectFactory factory, int maxIdle) {
99         this(factory,maxIdle,DEFAULT_INIT_SLEEPING_CAPACITY);
100     }
101
102     /**
103      * Create a new <tt>SimpleObjectPool</tt> using
104      * the specified <i>factory</i> to create new instances,
105      * capping the number of "sleeping" instances to <i>max</i>,
106      * and initially allocating a container capable of containing
107      * at least <i>init</i> instances.
108      *
109      * @param factory the {@link PoolableObjectFactory} used to populate the pool
110      * @param maxIdle cap on the number of "sleeping" instances in the pool
111      * @param initIdleCapacity initial size of the pool (this specifies the size of the container,
112      * it does not cause the pool to be pre-populated.)
113      */

114     public StackObjectPool(PoolableObjectFactory factory, int maxIdle, int initIdleCapacity) {
115         _factory = factory;
116         _maxSleeping = (maxIdle < 0 ? DEFAULT_MAX_SLEEPING : maxIdle);
117         int initcapacity = (initIdleCapacity < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : initIdleCapacity);
118         _pool = new Stack JavaDoc();
119         _pool.ensureCapacity( initcapacity > _maxSleeping ? _maxSleeping : initcapacity);
120     }
121
122     public synchronized Object JavaDoc borrowObject() throws Exception JavaDoc {
123         assertOpen();
124         Object JavaDoc obj = null;
125         if (!_pool.empty()) {
126             obj = _pool.pop();
127         } else {
128             if(null == _factory) {
129                 throw new NoSuchElementException JavaDoc();
130             } else {
131                 obj = _factory.makeObject();
132             }
133         }
134         if(null != _factory && null != obj) {
135             _factory.activateObject(obj);
136         }
137         _numActive++;
138         return obj;
139     }
140
141     public void returnObject(Object JavaDoc obj) throws Exception JavaDoc {
142         assertOpen();
143         boolean success = true;
144         if(null != _factory) {
145             if(!(_factory.validateObject(obj))) {
146                 success = false;
147             } else {
148                 try {
149                     _factory.passivateObject(obj);
150                 } catch(Exception JavaDoc e) {
151                     success = false;
152                 }
153             }
154         }
155
156         boolean shouldDestroy = !success;
157
158         synchronized(this) {
159             _numActive--;
160             if (success) {
161                 Object JavaDoc toBeDestroyed = null;
162                 if(_pool.size() >= _maxSleeping) {
163                     shouldDestroy = true;
164                     toBeDestroyed = _pool.remove(0); // remove the stalest object
165
}
166                 _pool.push(obj);
167                 obj = toBeDestroyed; // swap returned obj with the stalest one so it can be destroyed
168
}
169             notifyAll(); // _numActive has changed
170
}
171
172         if(shouldDestroy) { // by constructor, shouldDestroy is false when _factory is null
173
try {
174                 _factory.destroyObject(obj);
175             } catch(Exception JavaDoc e) {
176                 // ignored
177
}
178         }
179     }
180
181     public synchronized void invalidateObject(Object JavaDoc obj) throws Exception JavaDoc {
182         assertOpen();
183         _numActive--;
184         if(null != _factory ) {
185             _factory.destroyObject(obj);
186         }
187         notifyAll(); // _numActive has changed
188
}
189
190     public int getNumIdle() {
191         assertOpen();
192         return _pool.size();
193     }
194
195     public int getNumActive() {
196         assertOpen();
197         return _numActive;
198     }
199
200     public synchronized void clear() {
201         assertOpen();
202         if(null != _factory) {
203             Iterator JavaDoc it = _pool.iterator();
204             while(it.hasNext()) {
205                 try {
206                     _factory.destroyObject(it.next());
207                 } catch(Exception JavaDoc e) {
208                     // ignore error, keep destroying the rest
209
}
210             }
211         }
212         _pool.clear();
213     }
214
215     synchronized public void close() throws Exception JavaDoc {
216         clear();
217         _pool = null;
218         _factory = null;
219         super.close();
220     }
221
222     /**
223      * Create an object, and place it into the pool.
224      * addObject() is useful for "pre-loading" a pool with idle objects.
225      * @throws Exception when the {@link #_factory} has a problem creating an object.
226      */

227     public void addObject() throws Exception JavaDoc {
228         Object JavaDoc obj = _factory.makeObject();
229         synchronized(this) {
230             _numActive++; // A little slimy - must do this because returnObject decrements it.
231
this.returnObject(obj);
232         }
233     }
234
235     synchronized public void setFactory(PoolableObjectFactory factory) throws IllegalStateException JavaDoc {
236         assertOpen();
237         if(0 < getNumActive()) {
238             throw new IllegalStateException JavaDoc("Objects are already active");
239         } else {
240             clear();
241             _factory = factory;
242         }
243     }
244
245     /** The default cap on the number of "sleeping" instances in the pool. */
246     protected static final int DEFAULT_MAX_SLEEPING = 8;
247
248     /**
249      * The default initial size of the pool
250      * (this specifies the size of the container, it does not
251      * cause the pool to be pre-populated.)
252      */

253     protected static final int DEFAULT_INIT_SLEEPING_CAPACITY = 4;
254
255     /** My pool. */
256     protected Stack JavaDoc _pool = null;
257
258     /** My {@link PoolableObjectFactory}. */
259     protected PoolableObjectFactory _factory = null;
260
261     /** The cap on the number of "sleeping" instances in the pool. */
262     protected int _maxSleeping = DEFAULT_MAX_SLEEPING;
263
264     /** Number of object borrowed but not yet returned to the pool. */
265     protected int _numActive = 0;
266 }
267
Popular Tags