对象池commons-pool框架的研究以及源代码分析(四)

来源:互联网 发布:网络驱动怎么检查 编辑:程序博客网 时间:2024/06/16 04:24

编写了一个关于GenericObjectPool的测试方法,代码如下:

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
UserFactory userFactory = new commonPool2().new UserFactory();//内部类的实例化方法,代码的可读性不强
GenericObjectPool.Config config = new GenericObjectPool.Config();
config.maxActive = 5;//最大对象数
config.maxIdle = 5;//最大空闲数
config.minIdle = 1;//最小空闲数
config.maxWait = 5*1000;//获取对象等待时间

//当然,还有很多属性可以配置,在代码分析中详细说明
ObjectPool objectPool = new GenericObjectPool(userFactory,config);

User user = (User)objectPool.borrowObject();
user.setId(1);
user.setUserName("testnam3");
System.out.println(user);
objectPool.returnObject(user);
//-----------------------------归还后再借对象
User user2 = (User)objectPool.borrowObject();
System.out.println(user2);

}

我们可以看到,与其他对象池不同的是多了一个配置,需要注意,这是一个内部类,继续看看GenericObjectPool代码:

public class GenericObjectPool extends BaseObjectPool implements ObjectPool {


 //静态属性
    public static final byte WHEN_EXHAUSTED_FAIL   = 0;//没有对象时报错
    public static final byte WHEN_EXHAUSTED_BLOCK  = 1;//没有对象时等待
    public static final byte WHEN_EXHAUSTED_GROW   = 2;//没有对象时生成新对象
    public static final int DEFAULT_MAX_IDLE  = 8;//最大空闲对象
    public static final int DEFAULT_MIN_IDLE = 0;//最小空闲对象
    public static final int DEFAULT_MAX_ACTIVE  = 8;//最大对象数
    public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;//没有对象时的状态
    public static final long DEFAULT_MAX_WAIT = -1L;//获取对象的等待时间
    public static final boolean DEFAULT_TEST_ON_BORROW = false;//借出对象时是否测试
    public static final boolean DEFAULT_TEST_ON_RETURN = false;//返回对象时是否测试
    public static final boolean DEFAULT_TEST_WHILE_IDLE = false;//对象空闲时是否测试
    public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L; //默认检测线程运行时间    
    public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;//每次检测对象个数
    public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;// 对象过期时间
    public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;//对象最小空闲时间


    //--- package constants -------------------------------------------

    private int _maxIdle = DEFAULT_MAX_IDLE;//最大空闲数
    private int _minIdle = DEFAULT_MIN_IDLE;//最小空闲数
    private int _maxActive = DEFAULT_MAX_ACTIVE;//最大数量
    private long _maxWait = DEFAULT_MAX_WAIT;//最大等待时间
    private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;//获取不到对象时动作
    private boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;//在借用对象时是否检测对象
    private boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;//在归还对象时是否检测对象
    private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;//是否测试空闲对象
    private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;//检测线程执行时间间隔
    private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;//每次检测对象个数
    private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;//对象过期时间
    private long _softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;//对象空闲时间
    private LinkedList _pool = null;//对象池(链表)
    private PoolableObjectFactory _factory = null;//对象状态管理工厂
    private int _numActive = 0;//对象池对象数量
    private Evictor _evictor = null;//检测线程
    private int evictLastIndex = -1;//最后检测对象索引

//定义对象检查线程
    static final Timer EVICTION_TIMER = new Timer(true);


    //这里省略构造函数一批

 
    public GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle, long softMinEvictableIdleTimeMillis) {
        _factory = factory;
        _maxActive = maxActive;
        switch(whenExhaustedAction) {
            case WHEN_EXHAUSTED_BLOCK:
            case WHEN_EXHAUSTED_FAIL:
            case WHEN_EXHAUSTED_GROW:
                _whenExhaustedAction = whenExhaustedAction;//这种写法值得学习,省去了很多的if else

                break;
            default:
                throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
        }
        _maxWait = maxWait;
        _maxIdle = maxIdle;
        _minIdle = minIdle;
        _testOnBorrow = testOnBorrow;
        _testOnReturn = testOnReturn;
        _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
        _numTestsPerEvictionRun = numTestsPerEvictionRun;
        _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
        _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
        _testWhileIdle = testWhileIdle;


        _pool = new LinkedList();//可以看出,此对象池是一个链表
        startEvictor(_timeBetweenEvictionRunsMillis);//启动对象检测线程
    }


//获取最大对象数量
    public synchronized int getMaxActive() {
        return _maxActive;
    }


//设置最大对象数量
    public synchronized void setMaxActive(int maxActive) {
        _maxActive = maxActive;
        notifyAll();
    }


//获取不到对象时动作
    public synchronized byte getWhenExhaustedAction() {
        return _whenExhaustedAction;
    }

//设置获取对象时无法获取时动作
    public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
        switch(whenExhaustedAction) {
            case WHEN_EXHAUSTED_BLOCK:
            case WHEN_EXHAUSTED_FAIL:
            case WHEN_EXHAUSTED_GROW:
                _whenExhaustedAction = whenExhaustedAction;
                notifyAll();
                break;
            default:
                throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
        }
    }



//获取最大等待时间
    public synchronized long getMaxWait() {
        return _maxWait;
    }

//设置最大等待时间
    public synchronized void setMaxWait(long maxWait) {
        _maxWait = maxWait;
        notifyAll();
    }


//获取空闲对象数量
    public synchronized int getMaxIdle() {
        return _maxIdle;
    }


//设置空闲对象数量
    public synchronized void setMaxIdle(int maxIdle) {
        _maxIdle = maxIdle;
        notifyAll();
    }

//设置最小空闲对象数量
    public synchronized void setMinIdle(int minIdle) {
        _minIdle = minIdle;
        notifyAll();
    }


//获取最小空闲对象数量
    public synchronized int getMinIdle() {
        return _minIdle;
    }


//获取借用对象时是否测试
    public synchronized boolean getTestOnBorrow() {
        return _testOnBorrow;
    }


//设置借用对象时是否测试
    public synchronized void setTestOnBorrow(boolean testOnBorrow) {
        _testOnBorrow = testOnBorrow;
    }

//获取归还对象时是否测试
    public synchronized boolean getTestOnReturn() {
        return _testOnReturn;
    }


//设置归还对象时是否测试
    public synchronized void setTestOnReturn(boolean testOnReturn) {
        _testOnReturn = testOnReturn;
    }


//获取对象检测线程执行时间间隔
    public synchronized long getTimeBetweenEvictionRunsMillis() {
        return _timeBetweenEvictionRunsMillis;
    }


    //设置对象检测线程执行时间间隔
    public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
        _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
        startEvictor(_timeBetweenEvictionRunsMillis);
    }


 //获取检测线程每次检测对象个数
    public synchronized int getNumTestsPerEvictionRun() {
        return _numTestsPerEvictionRun;
    }


//设置检测线程每次检测对象个数
    public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        _numTestsPerEvictionRun = numTestsPerEvictionRun;
    }


//获取检测线程
    public synchronized long getMinEvictableIdleTimeMillis() {
        return _minEvictableIdleTimeMillis;
    }


//设置对象最小超时时间
    public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
        _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }


//获取对象最小空闲时间
    public synchronized long getSoftMinEvictableIdleTimeMillis() {
        return _softMinEvictableIdleTimeMillis;
    }


    //设置对象最小空闲时间
    public synchronized void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) {
        _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
    }


  //获取空闲时是否测试对象
    public synchronized boolean getTestWhileIdle() {
        return _testWhileIdle;
    }


  //设置空闲时是否设置测试对象
    public synchronized void setTestWhileIdle(boolean testWhileIdle) {
        _testWhileIdle = testWhileIdle;
    }


//设置配置参数
    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();
    }


//借用对象
    public synchronized Object borrowObject() throws Exception {
        assertOpen();
        long starttime = System.currentTimeMillis();//获取当前时间
        for(;;) {//死循环
            ObjectTimestampPair pair = null;
 
            try {
                pair = (ObjectTimestampPair)(_pool.removeFirst());//获取第一个对象
            } catch(NoSuchElementException e) {
                ; /* ignored */
            }

            if(null == pair) {//如果对象为空
                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://等待
                            try {
                                if(_maxWait <= 0) {//如果最大时间小于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) {
                                // ignored
                            }
                            if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {//如果超过最大等待时间,就报错
                                throw new NoSuchElementException("Timeout waiting for idle object");
                            } else {
                                continue; // 继续循环
                            }
                        default:
                            throw new IllegalArgumentException("WhenExhaustedAction property " + _whenExhaustedAction + " not recognized.");
                    }
                }
            }
            _numActive++;


     
            boolean newlyCreated = false;
            if(null == pair) {
                try {
                    Object obj = _factory.makeObject();//创建对象
                    pair = new ObjectTimestampPair(obj);
                    newlyCreated = true;
                } finally {
                    if (!newlyCreated) {//不需要创建对象
                        // object cannot be created
                        _numActive--;
                        notifyAll();
                    }
                }
            }

 
            try {
                _factory.activateObject(pair.value);//激活对象
                if(_testOnBorrow && !_factory.validateObject(pair.value)) {//测试对象不通过
                    throw new Exception("ValidateObject failed");
                }
                return pair.value;
            }
            catch (Throwable e) {
                // object cannot be activated or is invalid
                _numActive--;
                notifyAll();
                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 synchronized void invalidateObject(Object obj) throws Exception {
        assertOpen();
        try {
            _factory.destroyObject(obj);
        }
        finally {
            _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 synchronized 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;


        if (decrementNumActive) {
            _numActive--;
        }
        if((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {
            shouldDestroy = true;
        } else if(success) {
            _pool.addLast(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;
        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()) {//如果对象池不为空
            ListIterator iter;
            if (evictLastIndex < 0) {//该变量记录在对象池的位置,如果小于0说明之前未进行检测
                iter = _pool.listIterator(_pool.size());
            } else {
                iter = _pool.listIterator(evictLastIndex);
            }
            for(int i=0,m=getNumTests();i<m;i++) {
                if(!iter.hasPrevious()) {//如果已经到了队列的最前点,就再从头开始
                    iter = _pool.listIterator(_pool.size());
                }
                boolean removeObject = false;
                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(); //记录检测最好在对象池中的位置
        } // if !empty
    }


//创建对象
    private void ensureMinIdle() throws Exception {
 
        int objectDeficit = calculateDeficit();//获取还能生成的对象数
        for ( int j = 0 ; j < objectDeficit && calculateDeficit() > 0 ; j++ ) {
            addObject();//添加对象
        }
    }

//计算还能生成的对象数
    private synchronized int calculateDeficit() {
        int objectDeficit = getMinIdle() - getNumIdle();//最小空闲数-当前空闲数
        if (_maxActive > 0) {//最大数量大于0
            int growLimit = Math.max(0, getMaxActive() - getNumActive() - getNumIdle());//还能生成的对象数
            objectDeficit = Math.min(objectDeficit, growLimit);//取最小的
        }
        return objectDeficit;
    }


//添加对象到对象池
    public synchronized void addObject() throws Exception {
        assertOpen();
        Object obj = _factory.makeObject();
        addObjectToPool(obj, false);
    }


 
 // 开始启动线程
    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) {//如果大于0
            return Math.min(_numTestsPerEvictionRun, _pool.size());//获取检测个数,如果大于池的大小,就获取池的大小
        } else {
            return(int)(Math.ceil((double)_pool.size()/Math.abs((double)_numTestsPerEvictionRun)));//如果小于0,就获取其绝对值得的倒数,比如-2,就获取二份之一,-3就获取三份之一
        }
    }


    //--- inner classes ----------------------------------------------


   //检测线程类
    private class Evictor extends TimerTask {
        public void run() {
            try {
                evict();
            } catch(Exception e) {
                // ignored
            }
            try {
                ensureMinIdle();
            } catch(Exception e) {
                // ignored
            }
        }
    }


//配置类
    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;
    }


}