⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generickeyedobjectpool.java

📁 Apache的通用池Jar包
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
    }

    /**
     * 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 #getTestWhileIdle
     * @see #setTimeBetweenEvictionRunsMillis
     */
    public synchronized void setTestWhileIdle(boolean testWhileIdle) {
        _testWhileIdle = testWhileIdle;
    }

    /**
     * Sets my configuration.
     * @see GenericKeyedObjectPool.Config
     */
    public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
        setMaxIdle(conf.maxIdle);
        setMaxActive(conf.maxActive);
        setMaxTotal(conf.maxTotal);
        setMaxWait(conf.maxWait);
        setWhenExhaustedAction(conf.whenExhaustedAction);
        setTestOnBorrow(conf.testOnBorrow);
        setTestOnReturn(conf.testOnReturn);
        setTestWhileIdle(conf.testWhileIdle);
        setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
        setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
        setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
    }

    //-- ObjectPool methods ------------------------------------------

    public synchronized Object borrowObject(Object key) throws Exception {
        long starttime = System.currentTimeMillis();
        boolean newlyCreated = false;
        for(;;) {
            CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.get(key));
            if(null == pool) {
                pool = new CursorableLinkedList();
                _poolMap.put(key,pool);
                _poolList.add(key);
            }
            ObjectTimestampPair pair = null;
            // if there are any sleeping, just grab one of those
            try {
                pair = (ObjectTimestampPair)(pool.removeFirst());
                if(null != pair) {
                    _totalIdle--;
                }
            } catch(NoSuchElementException e) { /* ignored */
            }
            // otherwise
            if(null == pair) {
                // if there is a totalMaxActive and we are at the limit then
                // we have to make room
                // TODO: this could be improved by only removing the oldest object
                if ((_maxTotal > 0) && (_totalActive + _totalIdle >= _maxTotal)) {
                    clear();
                }
                
                // check if we can create one
                // (note we know that the num sleeping is 0, else we wouldn't be here)
                int active = getActiveCount(key);
                if ((_maxActive <= 0 || active < _maxActive) &&
                    (_maxTotal <= 0 || _totalActive + _totalIdle < _maxTotal)) {
                    Object obj = _factory.makeObject(key);
                    pair = new ObjectTimestampPair(obj);
                    newlyCreated = true;
                } else {
                    // the pool is exhausted
                    switch(_whenExhaustedAction) {
                        case WHEN_EXHAUSTED_GROW:
                            Object obj = _factory.makeObject(key);
                            pair = new ObjectTimestampPair(obj);
                            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.");
                    }
                }
            }
            _factory.activateObject(key,pair.value);
            if(_testOnBorrow && !_factory.validateObject(key,pair.value)) {
                _factory.destroyObject(key,pair.value);
                if(newlyCreated) {
                    throw new NoSuchElementException("Could not create a validated object");
                } // else keep looping
            } else {
                incrementActiveCount(key);
                return pair.value;
            }
        }
    }

    public synchronized void clear() {
        for(Iterator keyiter = _poolList.iterator(); keyiter.hasNext(); ) {
            Object key = keyiter.next();
            CursorableLinkedList list = (CursorableLinkedList)(_poolMap.get(key));
            for(Iterator it = list.iterator(); it.hasNext(); ) {
                try {
                    _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
                } catch(Exception e) {
                    // ignore error, keep destroying the rest
                }
                it.remove();
            }
        }
        _poolMap.clear();
        _poolList.clear();
        _totalIdle = 0;
        notifyAll();
    }

    public synchronized void clear(Object key) {
        CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.remove(key));
        if(null == pool) {
            return;
        } else {
            _poolList.remove(key);
            for(Iterator it = pool.iterator(); it.hasNext(); ) {
                try {
                    _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
                } catch(Exception e) {
                    // ignore error, keep destroying the rest
                }
                it.remove();
                _totalIdle--;
            }
        }
        notifyAll();
    }

    public synchronized int getNumActive() {
        return _totalActive;
    }

    public synchronized int getNumIdle() {
        return _totalIdle;
    }

    public synchronized int getNumActive(Object key) {
        return getActiveCount(key);
    }

    public synchronized int getNumIdle(Object key) {
        try {
            return((CursorableLinkedList)(_poolMap.get(key))).size();
        } catch(Exception e) {
            return 0;
        }
    }

    public void returnObject(Object key, Object obj) throws Exception {

        // if we need to validate this object, do so
        boolean success = true; // whether or not this object passed validation
        if(_testOnReturn && !_factory.validateObject(key, obj)) {
            success = false;
            try {
                _factory.destroyObject(key, obj);
            } catch(Exception e) {
                // ignored
            }
        } else {
            try {
                _factory.passivateObject(key, obj);
            } catch(Exception e) {
                success = false;
            }
        }

        boolean shouldDestroy = false;
        synchronized(this) {
            // grab the pool (list) of objects associated with the given key
            CursorableLinkedList pool = (CursorableLinkedList) (_poolMap.get(key));
            // if it doesn't exist, create it
            if(null == pool) {
                pool = new CursorableLinkedList();
                _poolMap.put(key, pool);
                _poolList.add(key);
            }
            decrementActiveCount(key);
            // if there's no space in the pool, flag the object for destruction
            // else if we passivated succesfully, return it to the pool
            if(_maxIdle >= 0 && (pool.size() >= _maxIdle)) {
                shouldDestroy = true;
            } else if(success) {
                pool.addFirst(new ObjectTimestampPair(obj));
                _totalIdle++;
            }
            notifyAll();
        }

        if(shouldDestroy) {
            try {
                _factory.destroyObject(key, obj);
            } catch(Exception e) {
                // ignored?
            }
        }
    }

    public void invalidateObject(Object key, Object obj) throws Exception {
        try {
            _factory.destroyObject(key, obj);
        }
        finally {
            synchronized(this) {
                decrementActiveCount(key);
                notifyAll(); // _totalActive has changed
            }
        }
    }

    public void addObject(Object key) throws Exception {
        Object obj = _factory.makeObject(key);
        synchronized(this) {
            incrementActiveCount(key); // returnObject will decrement this
            returnObject(key,obj);
        }
    }

    public synchronized void close() throws Exception {
        clear();
        _poolList = null;
        _poolMap = null;
        _activeMap = null;
        if(null != _evictionCursor) {
            _evictionCursor.close();
            _evictionCursor = null;
        }
        if(null != _evictionKeyCursor) {
            _evictionKeyCursor.close();
            _evictionKeyCursor = null;
        }
        if(null != _evictor) {
            _evictor.cancel();
            _evictor = null;
        }
    }

    public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
        if(0 < getNumActive()) {
            throw new IllegalStateException("Objects are already active");
        } else {
            clear();
            _factory = factory;
        }
    }

    public synchronized void evict() throws Exception {
        Object key = null;
        for(int i=0,m=getNumTests();i<m;i++) {
            if(_poolMap.size() > 0) {
                // if we don't have a key cursor, then create one, and close any object cursor
                if(null == _evictionKeyCursor) {
                    _evictionKeyCursor = _poolList.cursor();
                    key = null;
                    if(null != _evictionCursor) {
                        _evictionCursor.close();
                        _evictionCursor = null;
                    }
                }
                // if we don't have an object cursor
                if(null == _evictionCursor) {
                    // if the _evictionKeyCursor has a next value, then use it
                    if(_evictionKeyCursor.hasNext()) {
                        key = _evictionKeyCursor.next();
                        CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.get(key));
                        _evictionCursor = pool.cursor(pool.size());
                    } else {
                        // else close the key cursor and loop back around
                        if(null != _evictionKeyCursor) {
                            _evictionKeyCursor.close();
                            _evictionKeyCursor = _poolList.cursor();
                            if(null != _evictionCursor) {
                                _evictionCursor.close();
                                _evictionCursor = null;
                            }
                        }
                        continue;
                    }
                }
                // if the _evictionCursor has a previous object, then test it
                if(_evictionCursor.hasPrevious()) {
                    ObjectTimestampPair pair = (ObjectTimestampPair)(_evictionCursor.previous());
                    boolean removeObject=false;
                    if(_minEvictableIdleTimeMillis > 0 &&
                       System.currentTimeMillis() - pair.tstamp > _minEvictableIdleTimeMillis) {
                       removeObject=true;
                    } else if(_testWhileIdle) {
                        boolean active = false;
                        try {
                            _factory.activateObject(key,pair.value);
                            active = true;
                        } catch(Exception e) {
                            removeObject=true;
                        }
                        if(active) {
                            if(!_factory.validateObject(key,pair.value)) {
                                removeObject=true;
                            } else {
                                try {
                                    _factory.passivateObject(key,pair.value);
                                } catch(Exception e) {
                                    removeObject=true;
                                }
                            }
                        }
                    }
                    if(removeObject) {
                        try {
                            _evictionCursor.remove();
                            _totalIdle--;
                            _factory.destroyObject(key,pair.value);

                            // if that was the last object for that key, drop that pool
                            if( ((CursorableLinkedList)(_poolMap.get(key))).isEmpty() ) {
                                _poolMap.remove(key);
                                _poolList.remove(key);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -