我们知道频繁的创建对象是一个相对较重的过程,jvm要加载类,初始化对象,为对象分配内存涉及到多个系统调用,这样对一个高负载的系统来说是比较消耗资源的。这时我们可以将所需对象进行池化,apache开源的的commons-pool是一个比较经典的实现对象池化组件,笔者所在的公司在多个框架中都使用过这个组件,还有很多业界知名的中间件如Redis客户端Jedis等都使用到了这个池化组件。我们虽然不必重复造轮子,但是我们也得了解这个轮子是怎么造的。
接下来我们就从commons-pool的类层次设计、实现原理、使用这三个方面来研究一下commons-pool,我们这里以commons-pool-1.6源码进行分析,源码和jar包可以在这个链接中下载commons-pool源码和jar包官方下载。
首先我们先解释如下几个概念:
对象池:就是我们要介绍的commons-pool的核心概念,类似于容器,用于存放我们需要池化的对象
对象池工厂:就是操作对象池的工程(类似于设计模式中的工程模式),这个工厂可以执行借出、归还、销毁等管理池对象的操作
池对象:就是我们需要池化的对象
池对象工厂:就是操作池对象的工厂,比如生成、验证、激活、钝化、销毁池对象
(1)commons-pool类的层次设计
这个是Commons-pool的源码包,只有两个包org.apache.commons.pool这个包下大部分都是接口和抽象类,org.apache.commons.pool.impl这个是用户可以直接使用的接口或抽象类的具体实现。
public class GenericObjectPool<T> extends BaseObjectPool<T> implements ObjectPool<T>
ObjectPool是一个顶层接口,里面定义了对象池的一些基本操作,BaseObjectPool是一个抽象类对上层接口提供了缺省实现,作为一个用户层的默认缓冲实现,这样用户就不必全部实现顶层接口的所有方法,这种缺省模式在很多地方都可以使用,GenericObjectPool是一个具体的对象池的实现。
public interface ObjectPool {
//从对象池中借出对象
public abstract Object borrowObject() throws Exception,NoSuchElementException, IllegalStateException;
//将对象归还到对象池中
public abstract void returnObject(Object obj) throws Exception;
//使一个对象无效
public abstract void invalidateObject(Object obj) throws Exception;
//向对象池中添加对象
public abstract void addObject() throws Exception, IllegalStateException,UnsupportedOperationException;
//得到当前对象池中空闲的对象
public abstract int getNumIdle() throws UnsupportedOperationException;
//得到当前对象池已经借出的对象,这里的激活其实就是对象池借出对象的概念
public abstract int getNumActive() throws UnsupportedOperationException;
//清空对象池,并销毁对象池中的所有对象
public abstract void clear() throws Exception,UnsupportedOperationException;
// 关闭对象池
public abstract void close() throws Exception;
/**
* @deprecated Method setFactory is deprecated
*这个方法已经弃用了,池对象工程需要在实现类的构造函数中传入
*/
public abstract void setFactory(PoolableObjectFactory poolableobjectfactory)
throws IllegalStateException, UnsupportedOperationException;
}
public a