📄 genericobjectpool.java
字号:
_numTestsPerEvictionRun = numTestsPerEvictionRun;
}
/**
* Returns 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).
*
* @see #setMinEvictableIdleTimeMillis
* @see #setTimeBetweenEvictionRunsMillis
*/
public synchronized long getMinEvictableIdleTimeMillis() {
return _minEvictableIdleTimeMillis;
}
/**
* Sets 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 #getMinEvictableIdleTimeMillis
* @see #setTimeBetweenEvictionRunsMillis
*/
public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
_minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
/**
* 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 #setTimeBetweenEvictionRunsMillis
*/
public synchronized boolean getTestWhileIdle() {
return _testWhileIdle;
}
/**
* 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 #getTestWhileIdle
* @see #setTimeBetweenEvictionRunsMillis
*/
public synchronized void setTestWhileIdle(boolean testWhileIdle) {
_testWhileIdle = testWhileIdle;
}
/**
* Sets my configuration.
* @see GenericObjectPool.Config
*/
public synchronized void setConfig(GenericObjectPool.Config conf) {
setMaxIdle(conf.maxIdle);
setMinIdle(conf.minIdle);
setMaxActive(conf.maxActive);
setMaxWait(conf.maxWait);
setWhenExhaustedAction(conf.whenExhaustedAction);
setTestOnBorrow(conf.testOnBorrow);
setTestOnReturn(conf.testOnReturn);
setTestWhileIdle(conf.testWhileIdle);
setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
notifyAll();
}
//-- ObjectPool methods ------------------------------------------
public Object borrowObject() throws Exception {
long starttime = System.currentTimeMillis();
boolean newlyCreated = false;
for(;;) {
ObjectTimestampPair pair = null;
synchronized(this) {
assertOpen();
// if there are any sleeping, just grab one of those
try {
pair = (ObjectTimestampPair)(_pool.removeFirst());
} catch(NoSuchElementException e) {
; /* ignored */
}
// otherwise
if(null == pair) {
// check if we can create one
// (note we know that the num sleeping is 0, else we wouldn't be here)
if(_maxActive <= 0 || _numActive < _maxActive) {
// allow new object to be created
} else {
// the pool is exhausted
switch(_whenExhaustedAction) {
case WHEN_EXHAUSTED_GROW:
// allow new object to be created
break;
case WHEN_EXHAUSTED_FAIL:
throw new NoSuchElementException();
case WHEN_EXHAUSTED_BLOCK:
try {
if(_maxWait <= 0) {
wait();
} else {
wait(_maxWait);
}
} catch(InterruptedException e) {
// ignored
}
if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
throw new NoSuchElementException("Timeout waiting for idle object");
} else {
continue; // keep looping
}
default:
throw new IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " not recognized.");
}
}
}
_numActive++;
} // end synchronized
// create new object when needed
if(null == pair) {
try {
Object obj = _factory.makeObject();
pair = new ObjectTimestampPair(obj);
newlyCreated = true;
}
catch (Exception e) {
// object cannot be created
synchronized(this) {
_numActive--;
notifyAll();
}
throw e;
}
}
// activate & validate the object
try {
_factory.activateObject(pair.value);
if(_testOnBorrow && !_factory.validateObject(pair.value)) {
throw new Exception("validateObject failed");
}
return pair.value;
}
catch (Exception e) {
// object cannot be activated or is invalid
synchronized(this) {
_numActive--;
notifyAll();
}
try {
_factory.destroyObject(pair.value);
}
catch (Exception e2) {
// cannot destroy broken object
}
if(newlyCreated) {
throw new NoSuchElementException("Could not create a validated object, cause: " + e.getMessage());
}
else {
continue; // keep looping
}
}
}
}
public void invalidateObject(Object obj) throws Exception {
assertOpen();
try {
_factory.destroyObject(obj);
}
finally {
synchronized(this) {
_numActive--;
notifyAll(); // _numActive has changed
}
}
}
public synchronized void clear() {
assertOpen();
for(Iterator it = _pool.iterator(); it.hasNext(); ) {
try {
_factory.destroyObject(((ObjectTimestampPair)(it.next())).value);
} catch(Exception e) {
// ignore error, keep destroying the rest
}
it.remove();
}
_pool.clear();
notifyAll(); // num sleeping has changed
}
public synchronized int getNumActive() {
assertOpen();
return _numActive;
}
public synchronized int getNumIdle() {
assertOpen();
return _pool.size();
}
public void returnObject(Object obj) throws Exception {
assertOpen();
addObjectToPool(obj, true);
}
private void addObjectToPool(Object obj, boolean decrementNumActive) throws Exception {
boolean success = true;
if(_testOnReturn && !(_factory.validateObject(obj))) {
success = false;
} else {
try {
_factory.passivateObject(obj);
} catch(Exception e) {
success = false;
}
}
boolean shouldDestroy = !success;
synchronized(this) {
if (decrementNumActive) {
_numActive--;
}
if((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {
shouldDestroy = true;
} else if(success) {
_pool.addFirst(new ObjectTimestampPair(obj));
}
notifyAll(); // _numActive has changed
}
if(shouldDestroy) {
try {
_factory.destroyObject(obj);
} catch(Exception e) {
// ignored
}
}
}
public synchronized void close() throws Exception {
clear();
_pool = null;
_factory = null;
if(null != _evictionCursor) {
_evictionCursor.close();
_evictionCursor = null;
}
startEvictor(-1L);
super.close();
}
public synchronized void setFactory(PoolableObjectFactory factory) throws IllegalStateException {
assertOpen();
if(0 < getNumActive()) {
throw new IllegalStateException("Objects are already active");
} else {
clear();
_factory = factory;
}
}
public synchronized void evict() throws Exception {
assertOpen();
if(!_pool.isEmpty()) {
if(null == _evictionCursor) {
_evictionCursor = (_pool.cursor(_pool.size()));
} else if(!_evictionCursor.hasPrevious()) {
_evictionCursor.close();
_evictionCursor = (_pool.cursor(_pool.size()));
}
for(int i=0,m=getNumTests();i<m;i++) {
if(!_evictionCursor.hasPrevious()) {
_evictionCursor.close();
_evictionCursor = (_pool.cursor(_pool.size()));
} else {
boolean removeObject = false;
ObjectTimestampPair pair = (ObjectTimestampPair)(_evictionCursor.previous());
if(_minEvictableIdleTimeMillis > 0 &&
System.currentTimeMillis() - pair.tstamp > _minEvictableIdleTimeMillis) {
removeObject = true;
} else if(_testWhileIdle) {
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 {
_evictionCursor.remove();
_factory.destroyObject(pair.value);
} catch(Exception e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -