001: package net.xoetrope.optional.pool;
002:
003: import java.util.Enumeration;
004: import java.util.Vector;
005:
006: /**
007: * <p>Manages object pools</p>
008: * <p>Copyright (c) Xoetrope Ltd. 2001-2003</p>
009: * $Revision: 1.1 $
010: */
011: public abstract class PoolManager {
012: /**
013: * The timeout for dead objects
014: */
015: final private long timeout = 60000;
016:
017: /**
018: * The default pool size
019: */
020: private int poolSize = 10;
021:
022: /**
023: * The object pool data store
024: */
025: protected Vector objects;
026:
027: /**
028: * Recovers dead objects
029: */
030: private ObjectReaper objectReaper;
031:
032: /**
033: * Creates a new pool.
034: * @param size the number of objects for the initial pool size
035: */
036: public PoolManager(int size) {
037: poolSize = size;
038: objects = new Vector(poolSize);
039: objectReaper = new ObjectReaper(this );
040: objectReaper.start();
041: }
042:
043: /**
044: * Removes dead objects from the pool
045: */
046: public synchronized void reapObjects() {
047: long stale = System.currentTimeMillis() - timeout;
048: Enumeration objectList = objects.elements();
049:
050: while ((objectList != null) && objectList.hasMoreElements()) {
051: PoolObject poolObject = (PoolObject) objectList
052: .nextElement();
053:
054: if (poolObject.getInUse()
055: && (stale > poolObject.getLastUse())
056: && !poolObject.validate())
057: removeObject(poolObject);
058: }
059: }
060:
061: /**
062: * Closes and removes all objects in the pool
063: */
064: public synchronized void closeObjects() {
065: Enumeration objectList = objects.elements();
066:
067: while ((objects != null) && objectList.hasMoreElements()) {
068: PoolObject poolObject = (PoolObject) objectList
069: .nextElement();
070: removeObject(poolObject);
071: }
072: }
073:
074: /**
075: * Remove the object from the pool
076: * @param poolObject
077: */
078: private synchronized void removeObject(PoolObject poolObject) {
079: objects.removeElement(poolObject);
080: }
081:
082: /**
083: * Get a new object from the pool. A lease is granted to the new object
084: * @param name the name of the resource, for example the connection name
085: * @return a new PoolObject
086: * @throws Exception
087: */
088: public PoolObject getObject(String name) throws Exception {
089: PoolObject c;
090:
091: for (int i = 0; i < objects.size(); i++) {
092: c = (PoolObject) objects.elementAt(i);
093: if (c.lease())
094: return c;
095: }
096:
097: c = getNewObject(name);
098: c.lease();
099: objects.addElement(c);
100:
101: return c;
102: }
103:
104: /**
105: * Construct an new instance of a pooled object
106: * @return
107: * @throws Exception
108: */
109: public abstract PoolObject getNewObject(String name)
110: throws Exception;
111:
112: public synchronized void returnObject(PoolObject poolObject) {
113: poolObject.expireLease();
114: }
115: }
116:
117: /**
118: * <p>Description: Remove dead objects from the object pool</p>
119: * <p>Copyright (c) Xoetrope Ltd. 2001-2003</p>
120: * $Revision: 1.1 $
121: * @author Luan O'Carroll
122: */
123: class ObjectReaper extends Thread {
124: private PoolManager poolManager;
125: private final long delay = 300000;
126:
127: ObjectReaper(PoolManager pool) {
128: poolManager = pool;
129: }
130:
131: public void run() {
132: while (true) {
133: try {
134: sleep(delay);
135: } catch (InterruptedException e) {
136: }
137:
138: poolManager.reapObjects();
139: }
140: }
141: }
|