📄 generickeyedobjectpool.java
字号:
}
} catch(Exception e) {
; // ignored
}
}
} else {
// else the _evictionCursor is done, so close it and loop around
if(_evictionCursor != null) {
_evictionCursor.close();
_evictionCursor = null;
}
}
}
}
}
//--- non-public methods ----------------------------------------
/**
* Start the eviction thread or service, or when
* <i>delay</i> is non-positive, stop it
* if it is already running.
*/
protected synchronized void startEvictor(long delay) {
if(null != _evictor) {
_evictor.cancel();
_evictor = null;
}
if(delay > 0) {
_evictor = new Evictor(delay);
Thread t = new Thread(_evictor);
t.setDaemon(true);
t.start();
}
}
synchronized String debugInfo() {
StringBuffer buf = new StringBuffer();
buf.append("Active: ").append(getNumActive()).append("\n");
buf.append("Idle: ").append(getNumIdle()).append("\n");
Iterator it = _poolList.iterator();
while(it.hasNext()) {
buf.append("\t").append(_poolMap.get(it.next())).append("\n");
}
return buf.toString();
}
private synchronized int getNumTests() {
if(_numTestsPerEvictionRun >= 0) {
return _numTestsPerEvictionRun;
} else {
return(int)(Math.ceil((double)_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
}
}
private synchronized void incrementActiveCount(Object key) {
_totalActive++;
Integer active = (Integer)(_activeMap.get(key));
if(null == active) {
_activeMap.put(key,new Integer(1));
} else {
_activeMap.put(key,new Integer(active.intValue() + 1));
}
}
private synchronized void decrementActiveCount(Object key) {
_totalActive--;
Integer active = (Integer)(_activeMap.get(key));
if(null == active) {
// do nothing, either null or zero is OK
} else if(active.intValue() <= 1) {
_activeMap.remove(key);
} else {
_activeMap.put(key, new Integer(active.intValue() - 1));
}
}
private synchronized int getActiveCount(Object key) {
int active = 0;
Integer act = (Integer)(_activeMap.get(key));
if(null != act) {
active = act.intValue();
}
return active;
}
//--- inner classes ----------------------------------------------
/**
* A simple "struct" encapsulating an object instance and a timestamp.
*/
class ObjectTimestampPair {
Object value;
long tstamp;
ObjectTimestampPair(Object val) {
value = val;
tstamp = System.currentTimeMillis();
}
ObjectTimestampPair(Object val, long time) {
value = val;
tstamp = time;
}
public String toString() {
return value + ";" + tstamp;
}
}
/**
* The idle object evictor thread.
* @see #setTimeBetweenEvictionRunsMillis
*/
class Evictor implements Runnable {
private boolean _cancelled = false;
private long _delay = 0L;
public Evictor(long delay) {
_delay = delay;
}
void cancel() {
_cancelled = true;
}
public void run() {
while(!_cancelled) {
long sleeptime = 0L;
synchronized(GenericKeyedObjectPool.this) {
sleeptime = _timeBetweenEvictionRunsMillis;
}
try {
Thread.sleep(sleeptime);
} catch(Exception e) {
; // ignored
}
try {
evict();
} catch(Exception e) {
; // ignored
}
}
synchronized(GenericKeyedObjectPool.this) {
if(null != _evictionCursor) {
_evictionCursor.close();
_evictionCursor = null;
}
if(null != _evictionKeyCursor) {
_evictionKeyCursor.close();
_evictionKeyCursor = null;
}
}
}
}
/**
* A simple "struct" encapsulating the
* configuration information for a {@link GenericKeyedObjectPool}.
* @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
* @see GenericKeyedObjectPool#setConfig
*/
public static class Config {
public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
public int numTestsPerEvictionRun = GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
}
//--- protected attributes ---------------------------------------
/**
* The cap on the number of idle instances in the pool (per key).
* @see #setMaxIdle
* @see #getMaxIdle
*/
private int _maxIdle = DEFAULT_MAX_IDLE;
/**
* The cap on the number of active instances from the pool (per key).
* @see #setMaxActive
* @see #getMaxActive
*/
private int _maxActive = DEFAULT_MAX_ACTIVE;
/**
* The cap on the total number of instances from the pool.
* @see #setMaxTotal
* @see #getMaxTotal
*/
private int _maxTotal = DEFAULT_MAX_TOTAL;
/**
* The maximum amount of time (in millis) the
* {@link #borrowObject} method should block before throwing
* an exception when the pool is exhausted and the
* {@link #getWhenExhaustedAction "when exhausted" action} is
* {@link #WHEN_EXHAUSTED_BLOCK}.
*
* When less than 0, the {@link #borrowObject} method
* may block indefinitely.
*
* @see #setMaxWait
* @see #getMaxWait
* @see #WHEN_EXHAUSTED_BLOCK
* @see #setWhenExhaustedAction
* @see #getWhenExhaustedAction
*/
private long _maxWait = DEFAULT_MAX_WAIT;
/**
* The action to take when the {@link #borrowObject} method
* is invoked when the pool is exhausted (the maximum number
* of "active" objects has been reached).
*
* @see #WHEN_EXHAUSTED_BLOCK
* @see #WHEN_EXHAUSTED_FAIL
* @see #WHEN_EXHAUSTED_GROW
* @see #DEFAULT_WHEN_EXHAUSTED_ACTION
* @see #setWhenExhaustedAction
* @see #getWhenExhaustedAction
*/
private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
/**
* When <tt>true</tt>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned by the {@link #borrowObject}
* method. If the object fails to validate,
* it will be dropped from the pool, and we will attempt
* to borrow another.
*
* @see #setTestOnBorrow
* @see #getTestOnBorrow
*/
private boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
/**
* When <tt>true</tt>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* before being returned to the pool within the
* {@link #returnObject}.
*
* @see #getTestOnReturn
* @see #setTestOnReturn
*/
private boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
/**
* When <tt>true</tt>, objects will be
* {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
* by the idle object evictor (if any). If an object
* fails to validate, it will be dropped from the pool.
*
* @see #setTestWhileIdle
* @see #getTestWhileIdle
* @see #getTimeBetweenEvictionRunsMillis
* @see #setTimeBetweenEvictionRunsMillis
*/
private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
/**
* The number of milliseconds to sleep between runs of the
* idle object evictor thread.
* When non-positive, no idle object evictor thread will be
* run.
*
* @see #setTimeBetweenEvictionRunsMillis
* @see #getTimeBetweenEvictionRunsMillis
*/
private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
/**
* The number of objects to examine during each run of the
* idle object evictor thread (if any).
* <p>
* When a negative value is supplied, <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
* tests will be run. I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
* idle objects will be tested per run.
*
* @see #setNumTestsPerEvictionRun
* @see #getNumTestsPerEvictionRun
* @see #getTimeBetweenEvictionRunsMillis
* @see #setTimeBetweenEvictionRunsMillis
*/
private int _numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
/**
* The minimum amount of time an object may sit idle in the pool
* before it is eligable for eviction by the idle object evictor
* (if any).
* When non-positive, no objects will be evicted from the pool
* due to idle time alone.
*
* @see #setMinEvictableIdleTimeMillis
* @see #getMinEvictableIdleTimeMillis
* @see #getTimeBetweenEvictionRunsMillis
* @see #setTimeBetweenEvictionRunsMillis
*/
private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
/** My hash of pools (CursorableLinkedLists). */
private HashMap _poolMap = null;
/**
* A cursorable list of my pools.
* @see GenericKeyedObjectPool.Evictor#run
*/
private CursorableLinkedList _poolList = null;
/** Count of active objects, per key. */
private HashMap _activeMap = null;
/** The total number of active instances. */
private int _totalActive = 0;
/** The total number of idle instances. */
private int _totalIdle = 0;
/** My {@link KeyedPoolableObjectFactory}. */
private KeyedPoolableObjectFactory _factory = null;
/**
* My idle object eviction thread, if any.
*/
private Evictor _evictor = null;
private CursorableLinkedList.Cursor _evictionCursor = null;
private CursorableLinkedList.Cursor _evictionKeyCursor = null;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -