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

来源:互联网 发布:centos ftp客户端下载 编辑:程序博客网 时间:2024/06/08 10:50

再来看看Keyed类型的对象池, 先上类图:


这图是不是很眼熟?您没有看错,我也没有贴错,Keyed类型的对象池跟普通的对象池基本上调用方式相同,类的结构也相同,唯一不同的是操作对象时需要键值,这样就可以把不同类型的对象,在同一个缓冲池中分类存储,先上一段演示代码:

public static void main(String[] args) {
        Object obj = null;
        KeyedPoolableObjectFactory factory
                = new KeyedPoolableObjectUserFactory();
        KeyedObjectPoolFactory poolFactory 
                = new StackKeyedObjectPoolFactory(factory);
        KeyedObjectPool pool = poolFactory.createPool();
        String key = null;
 
            for (long i = 0; i < 100 ; i++) {
                 key = "" + (int) (Math.random() * 10);
 
                obj = pool.borrowObject(key);
          //加上KEY后,缓冲池就会根据KEY分类存储
                pool.returnObject(key, obj);
                obj = null;
            }
 
 }

再来简单看一下代码,以StackKeyedObjectPool为例,其他的类推:

//带KEY的堆栈对象池

public class StackKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
  //构造函数
    public StackKeyedObjectPool(KeyedPoolableObjectFactory factory, int max, int init) {
        _factory = factory;
        _maxSleeping = (max < 0 ? DEFAULT_MAX_SLEEPING : max);
        _initSleepingCapacity = (init < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : init);
        _pools = new HashMap();//注意其类型
        _activeCount = new HashMap();//注意其类型
    }


    public synchronized Object borrowObject(Object key) throws Exception {
        Object obj = null;
        Stack stack = (Stack)(_pools.get(key));//根据KEY获取堆栈
        if(null == stack) {
            stack = new Stack();//如果为空就重新生成堆栈
            stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
            _pools.put(key,stack);//将堆栈放入池中
        }
        try {
            obj = stack.pop();//从堆栈取出元素
            _totIdle--;
        } catch(Exception e) {
            if(null == _factory) {
                throw new NoSuchElementException();
            } else {
                obj = _factory.makeObject(key);//创建对象
            }
        }
        if(null != obj && null != _factory) {
            _factory.activateObject(key,obj);//激活对象
        }
        incrementActiveCount(key);//某KEY的个数减1
        return obj;
    }

//归还对象
    public synchronized void returnObject(Object key, Object obj) throws Exception {
        decrementActiveCount(key);
        if(null == _factory || _factory.validateObject(key,obj)) {
            Stack stack = (Stack)(_pools.get(key));
            if(null == stack) {
                stack = new Stack();
                stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
                _pools.put(key,stack);
            }
            if(null != _factory) {
                try {
                    _factory.passivateObject(key,obj);
                } catch(Exception e) {
                    _factory.destroyObject(key,obj);
                    return;
                }
            }
            if(stack.size() < _maxSleeping) {
                stack.push(obj);
                _totIdle++;
            } else {
                if(null != _factory) {
                    _factory.destroyObject(key,obj);
                }
            }
        } else {
            if(null != _factory) {
                _factory.destroyObject(key,obj);
            }
        }
    }


    public synchronized void invalidateObject(Object key, Object obj) throws Exception {
        decrementActiveCount(key);
        if(null != _factory) {
            _factory.destroyObject(key,obj);
        }
        notifyAll(); // _totalActive has changed
    }

//添加对象
    public synchronized void addObject(Object key) throws Exception {
        Object obj = _factory.makeObject(key);
        incrementActiveCount(key);  
        returnObject(key,obj);
    }


    public int getNumIdle() {
        return _totIdle;
    }


    public int getNumActive() {
        return _totActive;
    }


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


    public synchronized int getNumIdle(Object key) {
        try {
            return((Stack)(_pools.get(key))).size();//获取某KEY的对象个数
        } catch(Exception e) {
            return 0;
        }
    }

//清除对象
    public synchronized void clear() {
        Iterator it = _pools.keySet().iterator();
        while(it.hasNext()) {
            Object key = it.next();
            Stack stack = (Stack)(_pools.get(key));
            destroyStack(key,stack);
        }
        _totIdle = 0;
        _pools.clear();
        _activeCount.clear();
    }


    public synchronized void clear(Object key) {
        Stack stack = (Stack)(_pools.remove(key));
        destroyStack(key,stack);
    }


    private synchronized void destroyStack(Object key, Stack stack) {
        if(null == stack) {
            return;
        } else {
            if(null != _factory) {
                Iterator it = stack.iterator();
                while(it.hasNext()) {
                    try {
                        _factory.destroyObject(key,it.next());
                    } catch(Exception e) {
                        // ignore error, keep destroying the rest
                    }
                }
            }
            _totIdle -= stack.size();
            _activeCount.remove(key);
            stack.clear();
        }
    }


    public synchronized String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append(getClass().getName());
        buf.append(" contains ").append(_pools.size()).append(" distinct pools: ");
        Iterator it = _pools.keySet().iterator();
        while(it.hasNext()) {
            Object key = it.next();
            buf.append(" |").append(key).append("|=");
            Stack s = (Stack)(_pools.get(key));
            buf.append(s.size());
        }
        return buf.toString();
    }


    public synchronized void close() throws Exception {
        clear();
        _pools = null;
        _factory = null;
        _activeCount = null;
    }


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


    private int getActiveCount(Object key) {
        try {
            return ((Integer)_activeCount.get(key)).intValue();
        } catch(NoSuchElementException e) {
            return 0;
        } catch(NullPointerException e) {
            return 0;
        }
    }


    private void incrementActiveCount(Object key) {
        _totActive++;
        Integer old = (Integer)(_activeCount.get(key));
        if(null == old) { 
            _activeCount.put(key,new Integer(1));
        } else {
            _activeCount.put(key,new Integer(old.intValue() + 1));
        }
    }


    private void decrementActiveCount(Object key) {
        _totActive--;
        Integer active = (Integer)(_activeCount.get(key));
        if(null == active) {
            // do nothing, either null or zero is OK
        } else if(active.intValue() <= 1) {
            _activeCount.remove(key);
        } else {
            _activeCount.put(key, new Integer(active.intValue() - 1));
        }
    }


    /** The default cap on the number of "sleeping" instances in the pool. */
    protected static final int DEFAULT_MAX_SLEEPING  = 8;


    /**
     * The default initial size of the pool
     * (this specifies the size of the container, it does not
     * cause the pool to be pre-populated.)
     */
    protected static final int DEFAULT_INIT_SLEEPING_CAPACITY = 4;


    /** My named-set of pools. */
    protected HashMap _pools = null;


    /** My {@link KeyedPoolableObjectFactory}. */
    protected KeyedPoolableObjectFactory _factory = null;


    /** The cap on the number of "sleeping" instances in <i>each</i> pool. */
    protected int _maxSleeping = DEFAULT_MAX_SLEEPING;


    /** The initial capacity of each pool. */
    protected int _initSleepingCapacity = DEFAULT_INIT_SLEEPING_CAPACITY;


    /** Total number of object borrowed and not yet retuened for all pools */
    protected int _totActive = 0;


    /** Total number of objects "sleeping" for all pools */
    protected int _totIdle = 0;


    /** Number of active objects borrowed and not yet returned by pool */
    protected HashMap _activeCount = null;


}









原创粉丝点击