📄 genericobjectpool.java
字号:
* @see #setTestWhileIdle * @see #setTimeBetweenEvictionRunsMillis */ public 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. * * @param testWhileIdle <code>true</code> so objects will be validated by the evictor. * @see #getTestWhileIdle * @see #setTimeBetweenEvictionRunsMillis */ public synchronized void setTestWhileIdle(boolean testWhileIdle) { _testWhileIdle = testWhileIdle; } /** * Whether or not the idle object pool acts as a LIFO queue. True means * that borrowObject returns the most recently used ("last in") idle object * in the pool (if there are idle instances available). False means that * the pool behaves as a FIFO queue - objects are taken from the idle object * pool in the order that they are returned to the pool. * * @return <code>true</true> if the pool is configured to act as a LIFO queue * @since 1.4 */ public synchronized boolean getLifo() { return _lifo; } /** * Sets the LIFO property of the pool. True means that borrowObject returns * the most recently used ("last in") idle object in the pool (if there are * idle instances available). False means that the pool behaves as a FIFO * queue - objects are taken from the idle object pool in the order that * they are returned to the pool. * * @param lifo the new value for the LIFO property * @since 1.4 */ public synchronized void setLifo(boolean lifo) { this._lifo = lifo; } /** * Sets my configuration. * * @param conf configuration to use. * @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); setSoftMinEvictableIdleTimeMillis(conf.softMinEvictableIdleTimeMillis); setLifo(conf.lifo); notifyAll(); } //-- ObjectPool methods ------------------------------------------ public Object borrowObject() throws Exception { long starttime = System.currentTimeMillis(); for(;;) { ObjectTimestampPair pair = null; lock.lock(); try { assertOpen(); // if there are any sleeping, just grab one of those try { pair = (ObjectTimestampPair)(_pool.removeFirst()); } catch(NoSuchElementException e) { ; /* ignored */ } }finally{ lock.unlock(); } // 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("Pool exhausted"); case WHEN_EXHAUSTED_BLOCK: synchronized(this){ try { if(_maxWait <= 0) { wait(); } else { // this code may be executed again after a notify then continue cycle // so, need to calculate the amount of time to wait final long elapsed = (System.currentTimeMillis() - starttime); final long waitTime = _maxWait - elapsed; if (waitTime > 0) { wait(waitTime); } } } catch(InterruptedException e) { Thread.currentThread().interrupt(); throw e; } } if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) { throw new NoSuchElementException("Timeout waiting for idle object"); } else { continue; // keep looping } default: throw new IllegalArgumentException("WhenExhaustedAction property " + _whenExhaustedAction + " not recognized."); } } } // create new object when needed boolean newlyCreated = false; boolean numIncreased = false; if(null == pair) { if(_maxActive < 0 || this.getNumActive() < _maxActive || _whenExhaustedAction != WHEN_EXHAUSTED_BLOCK) { lock.lock(); try { if(_numActive < _maxActive){ _numActive++; numIncreased = true; }else{ continue; } }finally{ lock.unlock(); } try{ Object obj = _factory.makeObject(); pair = new ObjectTimestampPair(obj); newlyCreated = true; }catch(Exception e){ lock.lock(); try { _numActive--; numIncreased = false; }finally{ lock.unlock(); } throw e; } }else{ continue; } } // activate & validate the object try { if(_testOnBorrow && !_factory.validateObject(pair.value)) { throw new Exception("ValidateObject failed"); } _factory.activateObject(pair.value); if(!numIncreased){ lock.lock(); try { _numActive++; numIncreased = true; }finally{ lock.unlock(); } } return pair.value; } catch (Throwable e) { if(numIncreased){ lock.lock(); try { _numActive--; }finally{ lock.unlock(); } } // object cannot be activated or is invalid try { _factory.destroyObject(pair.value); } catch (Throwable 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 { try { if (_factory != null) { _factory.destroyObject(obj); } } finally { lock.lock(); try { _numActive--; }finally{ lock.unlock(); } } } /** * Clears any objects sitting idle in the pool. */ public void clear() { lock.lock(); try{ 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 }finally{ lock.unlock(); } } /** * Return the number of instances currently borrowed from this pool. * * @return the number of instances currently borrowed from this pool */ public int getNumActive() { lock.lock(); try{ return _numActive; }finally{ lock.unlock(); } } /** * Return the number of instances currently idle in this pool. * * @return the number of instances currently idle in this pool */ public int getNumIdle() { lock.lock(); try{ return _pool.size(); }finally{ lock.unlock(); } } /** * {@inheritDoc} * <p><strong>Note: </strong> There is no guard to prevent an object * being returned to the pool multiple times. Clients are expected to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -