You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rd...@apache.org on 2006/02/14 21:46:01 UTC
svn commit: r377826 - in
/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl:
GenericKeyedObjectPool.java GenericObjectPool.java
Author: rdonkin
Date: Tue Feb 14 12:45:59 2006
New Revision: 377826
URL: http://svn.apache.org/viewcvs?rev=377826&view=rev
Log:
Switches from Thread to java.util.TimerTask for evictions. This is a far more efficient implementation for highly loaded systems. Original patch contributed by Matt Bishop. Patch committed contributed by Sandy McArthur. Issue #36581.
Modified:
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericObjectPool.java
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=377826&r1=377825&r2=377826&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java Tue Feb 14 12:45:59 2006
@@ -25,6 +25,7 @@
import java.util.TreeMap;
import java.util.LinkedList;
import java.util.HashSet;
+import java.util.TimerTask;
import org.apache.commons.pool.BaseKeyedObjectPool;
import org.apache.commons.pool.KeyedObjectPool;
@@ -576,7 +577,7 @@
public synchronized void setMinIdle(int poolSize) {
_minIdle = poolSize;
}
-
+
/**
* Returns the minimum number of idle objects in pool to maintain (per key)
* @return the minimum number of idle objects in pool to maintain (per key)
@@ -585,7 +586,7 @@
public synchronized int getMinIdle() {
return _minIdle;
}
-
+
/**
* When <tt>true</tt>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
@@ -867,7 +868,7 @@
}
/**
- * Method clears oldest 15% of objects in pool. The method sorts the
+ * Method clears oldest 15% of objects in pool. The method sorts the
* objects into a TreeMap and then iterates the first 15% for removal
*/
public synchronized void clearOldest() {
@@ -884,11 +885,11 @@
map.put(pair, key);
}
}
-
+
// Now iterate created map and kill the first 15% plus one to account for zero
Set setPairKeys = map.entrySet();
int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
-
+
Iterator iter = setPairKeys.iterator();
while (iter.hasNext() && itemsToRemove > 0) {
Map.Entry entry = (Map.Entry) iter.next();
@@ -914,7 +915,7 @@
}
notifyAll();
}
-
+
public synchronized void clear(Object key) {
LinkedList pool = (LinkedList)(_poolMap.remove(key));
if(null == pool) {
@@ -1017,12 +1018,12 @@
}
/**
- * Registers a key for pool control.
- *
+ * Registers a key for pool control.
+ *
* If <i>populateImmediately</i> is <code>true</code>, the pool will immediately commence
* a sustain cycle. If <i>populateImmediately</i> is <code>false</code>, the pool will be
* populated when the next schedules sustain task is run.
- *
+ *
* @param key - The key to register for pool control.
* @param populateImmediately - If this is <code>true</code>, the pool
* will start a sustain cycle immediately.
@@ -1033,7 +1034,7 @@
pool = new LinkedList();
_poolMap.put(key,pool);
}
-
+
if (populateImmediately) {
try {
// Create the pooled objects
@@ -1044,7 +1045,7 @@
}
}
}
-
+
public synchronized void close() throws Exception {
clear();
_poolMap = null;
@@ -1136,9 +1137,9 @@
_factory.destroyObject(key,pair.value);
// Do not remove the key from the _poolList or _poolmap, even if the list
- // stored in the _poolMap for this key is empty when the
+ // stored in the _poolMap for this key is empty when the
// {@link #getMinIdle <i>minIdle</i>} is > 0.
- //
+ //
// Otherwise if it was the last object for that key, drop that pool
if ((_minIdle == 0) && (((LinkedList)(_poolMap.get(key))).isEmpty())) {
_poolMap.remove(key);
@@ -1166,7 +1167,7 @@
*/
private synchronized void ensureMinIdle() throws Exception {
Iterator iterator = _poolMap.keySet().iterator();
-
+
//Check if should sustain the pool
if (_minIdle > 0) {
// Loop through all elements in _poolList
@@ -1184,7 +1185,7 @@
/**
* Re-creates any needed objects to maintain the minimum levels of
* pooled objects for the specified key.
- *
+ *
* This method uses {@link #calculateDefecit} to calculate the number
* of objects to be created. {@link #calculateDefecit} can be overridden to
* provide a different method of calculating the number of objects to be
@@ -1195,13 +1196,13 @@
private synchronized void ensureMinIdle(Object key) throws Exception {
// Calculate current pool objects
int numberToCreate = calculateDefecit(key);
-
+
//Create required pool objects, if none to create, this loop will not be run.
for (int i = 0; i < numberToCreate; i++) {
addObject(key);
}
}
-
+
//--- non-public methods ----------------------------------------
/**
@@ -1215,10 +1216,8 @@
_evictor = null;
}
if(delay > 0) {
- _evictor = new Evictor(delay);
- Thread t = new Thread(_evictor);
- t.setDaemon(true);
- t.start();
+ _evictor = new Evictor();
+ GenericObjectPool.EVICTION_TIMER.schedule(_evictor, delay, delay);
}
}
@@ -1271,23 +1270,23 @@
}
return active;
}
-
+
/**
* This returns the number of objects to create during the pool
- * sustain cycle. This will ensure that the minimum number of idle
+ * sustain cycle. This will ensure that the minimum number of idle
* connections is maintained without going past the maxPool value.
* <p>
- * This method has been left public so derived classes can override
- * the way the defecit is calculated. ie... Increase/decrease the pool
+ * This method has been left public so derived classes can override
+ * the way the defecit is calculated. ie... Increase/decrease the pool
* size at certain times of day to accomodate for usage patterns.
- *
+ *
* @param key - The key of the pool to calculate the number of
* objects to be re-created
* @return The number of objects to be created
*/
private int calculateDefecit(Object key) {
int objectDefecit = 0;
-
+
//Calculate no of objects needed to be created, in order to have
//the number of pooled objects < maxActive();
objectDefecit = getMinIdle() - getNumIdle(key);
@@ -1295,8 +1294,8 @@
int growLimit = Math.max(0, getMaxActive() - getNumActive(key) - getNumIdle(key));
objectDefecit = Math.min(objectDefecit, growLimit);
}
-
- // Take the maxTotal limit into account
+
+ // Take the maxTotal limit into account
if (getMaxTotal() > 0) {
int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle());
objectDefecit = Math.min(objectDefecit, growLimit);
@@ -1309,7 +1308,7 @@
/**
* A simple "struct" encapsulating an object instance and a timestamp.
- *
+ *
* Implements Comparable, objects are sorted from old to new.
*/
class ObjectTimestampPair implements Comparable {
@@ -1340,44 +1339,22 @@
}
/**
- * The idle object evictor thread.
+ * The idle object evictor {@link TimerTask}.
* @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
*/
- class Evictor implements Runnable {
- private boolean _cancelled = false;
- private long _delay = 0L;
-
- public Evictor(long delay) {
- _delay = delay;
- }
-
- void cancel() {
- _cancelled = true;
- }
-
+ private class Evictor extends TimerTask {
public void run() {
- while(!_cancelled) {
- long sleeptime = 0L;
- synchronized(GenericKeyedObjectPool.this) {
- sleeptime = _timeBetweenEvictionRunsMillis;
- }
- try {
- Thread.sleep(sleeptime);
- } catch(Exception e) {
- ; // ignored
- }
- //Evict from the pool
- try {
- evict();
- } catch(Exception e) {
- ; // ignored
- }
- //Re-create the connections.
- try {
- ensureMinIdle();
- } catch (Exception e) {
- ; // ignored
- }
+ //Evict from the pool
+ try {
+ evict();
+ } catch(Exception e) {
+ // ignored
+ }
+ //Re-create the connections.
+ try {
+ ensureMinIdle();
+ } catch (Exception e) {
+ // ignored
}
}
}
@@ -1558,7 +1535,7 @@
private KeyedPoolableObjectFactory _factory = null;
/**
- * My idle object eviction thread, if any.
+ * My idle object eviction {@link TimerTask}, if any.
*/
private Evictor _evictor = null;
Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericObjectPool.java?rev=377826&r1=377825&r2=377826&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericObjectPool.java Tue Feb 14 12:45:59 2006
@@ -20,6 +20,8 @@
import java.util.NoSuchElementException;
import java.util.LinkedList;
import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
import org.apache.commons.pool.BaseObjectPool;
import org.apache.commons.pool.ObjectPool;
@@ -257,6 +259,13 @@
*/
public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
+ //--- package constants -------------------------------------------
+
+ /**
+ * Idle object evition Timer. Shared between all {@link GenericObjectPool}s and {@link GenericKeyedObjectPool} s.
+ */
+ static final Timer EVICTION_TIMER = new Timer(true);
+
//--- constructors -----------------------------------------------
/**
@@ -1063,10 +1072,8 @@
_evictor = null;
}
if(delay > 0) {
- _evictor = new Evictor(delay);
- Thread t = new Thread(_evictor);
- t.setDaemon(true);
- t.start();
+ _evictor = new Evictor();
+ EVICTION_TIMER.schedule(_evictor, delay, delay);
}
}
@@ -1112,41 +1119,22 @@
}
/**
- * The idle object evictor thread.
+ * The idle object evictor {@link TimerTask}.
* @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
*/
- class Evictor implements Runnable {
- private volatile boolean _cancelled = false;
- private long _delay = 0L;
-
- public Evictor(long delay) {
- _delay = delay;
- }
-
- void cancel() {
- _cancelled = true;
- }
-
+ private class Evictor extends TimerTask {
public void run() {
- while(!_cancelled) {
- try {
- Thread.sleep(_delay);
- } catch(Exception e) {
- // ignored
- }
- try {
- evict();
- } catch(Exception e) {
- // ignored
- }
- try {
- ensureMinIdle();
- } catch(Exception e) {
- // ignored
- }
+ try {
+ evict();
+ } catch(Exception e) {
+ // ignored
+ }
+ try {
+ ensureMinIdle();
+ } catch(Exception e) {
+ // ignored
}
}
-
}
/**
@@ -1328,7 +1316,7 @@
private int _numActive = 0;
/**
- * My idle object eviction thread, if any.
+ * My idle object eviction {@link TimerTask}, if any.
*/
private Evictor _evictor = null;
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org