📄 genericobjectpool.java
字号:
final ObjectTimestampPair pair = (ObjectTimestampPair)(iter.previous()); final long idleTimeMilis = System.currentTimeMillis() - pair.tstamp; if ((_minEvictableIdleTimeMillis > 0) && (idleTimeMilis > _minEvictableIdleTimeMillis)) { removeObject = true; } else if ((_softMinEvictableIdleTimeMillis > 0) && (idleTimeMilis > _softMinEvictableIdleTimeMillis) && (getNumIdle() > getMinIdle())) { removeObject = true; } if(_testWhileIdle && !removeObject) { boolean active = false; try { _factory.activateObject(pair.value); active = true; } catch(Exception e) { removeObject=true; } if(active) { if(!_factory.validateObject(pair.value)) { removeObject=true; } else { try { _factory.passivateObject(pair.value); } catch(Exception e) { removeObject=true; } } } } if(removeObject) { try { iter.remove(); _factory.destroyObject(pair.value); } catch(Exception e) { // ignored } } } evictLastIndex = iter.previousIndex(); // resume from here } // if !empty } /** * Check to see if we are below our minimum number of objects * if so enough to bring us back to our minimum. */ private void ensureMinIdle() throws Exception { // this method isn't synchronized so the // calculateDeficit is done at the beginning // as a loop limit and a second time inside the loop // to stop when another thread already returned the // needed objects int objectDeficit = calculateDeficit(); for ( int j = 0 ; j < objectDeficit && calculateDeficit() > 0 ; j++ ) { addObject(); } } private synchronized int calculateDeficit() { int objectDeficit = getMinIdle() - getNumIdle(); if (_maxActive > 0) { int growLimit = Math.max(0, getMaxActive() - getNumActive() - getNumIdle()); objectDeficit = Math.min(objectDeficit, growLimit); } return objectDeficit; } /** * Create an object, and place it into the pool. * addObject() is useful for "pre-loading" a pool with idle objects. */ public synchronized void addObject() throws Exception { assertOpen(); Object obj = _factory.makeObject(); addObjectToPool(obj, false); } //--- 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(); EVICTION_TIMER.schedule(_evictor, delay, delay); } } synchronized String debugInfo() { StringBuffer buf = new StringBuffer(); buf.append("Active: ").append(getNumActive()).append("\n"); buf.append("Idle: ").append(getNumIdle()).append("\n"); buf.append("Idle Objects:\n"); Iterator it = _pool.iterator(); long time = System.currentTimeMillis(); while(it.hasNext()) { ObjectTimestampPair pair = (ObjectTimestampPair)(it.next()); buf.append("\t").append(pair.value).append("\t").append(time - pair.tstamp).append("\n"); } return buf.toString(); } private int getNumTests() { if(_numTestsPerEvictionRun >= 0) { return Math.min(_numTestsPerEvictionRun, _pool.size()); } else { return(int)(Math.ceil((double)_pool.size()/Math.abs((double)_numTestsPerEvictionRun))); } } //--- inner classes ---------------------------------------------- /** * The idle object evictor {@link TimerTask}. * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis */ private class Evictor extends TimerTask { public void run() { try { evict(); } catch(Exception e) { // ignored } try { ensureMinIdle(); } catch(Exception e) { // ignored } } } /** * A simple "struct" encapsulating the * configuration information for a {@link GenericObjectPool}. * @see GenericObjectPool#GenericObjectPool(org.apache.commons.pool.PoolableObjectFactory,org.apache.commons.pool.impl.GenericObjectPool.Config) * @see GenericObjectPool#setConfig */ public static class Config { public int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE; public int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE; public int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE; public long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT; public byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION; public boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW; public boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN; public boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE; public long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; public int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; public long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; public long softMinEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; } //--- private attributes --------------------------------------- /** * The cap on the number of idle instances in the pool. * @see #setMaxIdle * @see #getMaxIdle */ private int _maxIdle = DEFAULT_MAX_IDLE; /** * The cap on the minimum number of idle instances in the pool. * @see #setMinIdle * @see #getMinIdle */ private int _minIdle = DEFAULT_MIN_IDLE; /** * The cap on the total number of active instances from the pool. * @see #setMaxActive * @see #getMaxActive */ protected int _maxActive = DEFAULT_MAX_ACTIVE; /** * 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 */ protected 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 */ protected byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION; /** * When <tt>true</tt>, objects will be * {@link 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 */ protected boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW; /** * When <tt>true</tt>, objects will be * {@link 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 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 max 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; /** * 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), with the extra condition that at least * "minIdle" amount of object remain in the pool. * When non-positive, no objects will be evicted from the pool * due to idle time alone. * * @see #setSoftMinEvictableIdleTimeMillis * @see #getSoftMinEvictableIdleTimeMillis */ private long _softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS; /** My pool. */ protected LinkedList _pool = null; /** My {@link PoolableObjectFactory}. */ protected PoolableObjectFactory _factory = null; /** * The number of objects {@link #borrowObject} borrowed * from the pool, but not yet returned. */ protected int _numActive = 0; /** * My idle object eviction {@link TimerTask}, if any. */ private Evictor _evictor = null; /** * Position in the _pool where the _evictor last stopped. */ private int evictLastIndex = -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -