您的位置:首页 > 编程语言

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

2013-04-21 11:23 330 查看
通过上一节的例子,我们使用了一个简单的对象池应用,现在再来看看其内部是如何实现的。先看看主要包括了哪些类:



该包所有的类与接口不多,也就20个左右,虽然是一个小项目,其中接口与抽象类的数量,基本上与实现的类差不多,可以说明开发者是使用面向接口编程,而不是面向实现编程,对我们的开发工作有着指导意义,在开发中要尽量面向接口编程而非实现。把类整理一下,分成两类,一类是包括KEY的对象池,一类是不包括KEY的对象池,实际上,分析了其中一个,另外的不用分析都知道其实现,先画个简单的类图(没有一个好的画图工具,这图画得不够专业啊,大家将就着看):



绿色部分的类与接口,就是我们前面使用过的类与接口,StackObjectPool就是对象池的具体实现,由图中我们可以看到,对象池的实现,主要包括4类:StackObjectPool,GenericObjectPool,SoftReferenceObjectPool,AbandoneObjectPool。,值得一提的是BaseObjectPool类,其中负责对对象池状态来维护,实际上主要是维护一个isClose属性,不过在设计上,还是可取的,将通用的属性在一个抽象类里面维护。

左边部分,就是我们使用的对象状态维护工厂,由对象池具体实现操作,对对象的状态进行维护。

右边是使用了工厂设计模式,生成利用对象池工厂生成对象池,由于我们的代码只是演示,所以直接在代码中硬编码了,没有使用工厂,在实际编程中是不可取的。

对核心的类、接口有一个整体印象后,我们就可以来看其具体实现了,先来看看StackObjectPool类:

public class StackObjectPool extends BaseObjectPool implements ObjectPool {

先看看属性:

protected Stack _pool = null;//对象池,是一个Stack,后面可以想象,主要是围绕Stack做操作

protected static final int DEFAULT_MAX_SLEEPING = 8;//默认池中对象最大数量,注意是Static与final

protected static final int DEFAULT_INIT_SLEEPING_CAPACITY = 4;//默认初始化对象的数量,注意是Static与final

值得学习的地方:设置一些默认对象时,尽量设置为final,避免认为的非法修改

protected PoolableObjectFactory _factory = null;//对象状态维护工厂

protected int _maxSleeping = DEFAULT_MAX_SLEEPING;//最大对象数量

protected int _numActive = 0;//被借出对象数量

//设略构造函数5个,构造函数主要是对以上属性设置值

public StackObjectPool(PoolableObjectFactory factory, int maxIdle, int initIdleCapacity) {

_factory = factory;

_maxSleeping = (maxIdle < 0 ? DEFAULT_MAX_SLEEPING : maxIdle);

int initcapacity = (initIdleCapacity < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : initIdleCapacity);

_pool = new Stack();

_pool.ensureCapacity( initcapacity > _maxSleeping ? _maxSleeping : initcapacity);

//生成Stack对象,并对对象的大小做初始化

}

//借出对象

public synchronized Object borrowObject() throws Exception {

assertOpen();

Object obj = null;

while (null == obj) {

if (!_pool.empty()) {//如果对象池非空,就取出对象

obj = _pool.pop();

} else {//如果对象池为空,就调用我们传递进来的对象状态维护类来创建对象

if(null == _factory) {

throw new NoSuchElementException();

} else {

obj = _factory.makeObject();

}

}

if(null != _factory && null != obj) {//如果取出对象,就激活对象

_factory.activateObject(obj);

}

if (null != _factory && null != obj && !_factory.validateObject(obj)) {//如果对象验证对象不可用,就销毁掉并返回NULL

_factory.destroyObject(obj);

obj = null;

}

}

_numActive++;

return obj;

}

//返回对象

public synchronized void returnObject(Object obj) throws Exception {

assertOpen();

boolean success = true;

if(null != _factory) {

if(!(_factory.validateObject(obj))) {//如果对象无效

success = false;

} else {

try {

_factory.passivateObject(obj);//调用对象返回后的动作进行状态维护

} catch(Exception e) {

success = false;

}

}

}

boolean shouldDestroy = !success;

_numActive--;

if (success) {//对象有效

Object toBeDestroyed = null;

if(_pool.size() >= _maxSleeping) {

shouldDestroy = true;

toBeDestroyed = _pool.remove(0); // remove the stalest object

}

_pool.push(obj);

obj = toBeDestroyed; // swap returned obj with the stalest one so it can be destroyed

}

notifyAll(); // _numActive has changed

//这一段代码写得有点乱,原意是:如果对象数量超出最大限制,取出池中的对象,然后将有效对象放入,取出的对象就等着销毁

if(shouldDestroy) { // by constructor, shouldDestroy is false when _factory is null

try {

_factory.destroyObject(obj);

} catch(Exception e) {

// ignored

}

}

}

//将对象设置为无效

public synchronized void invalidateObject(Object obj) throws Exception {

assertOpen();

_numActive--;

if(null != _factory ) {

_factory.destroyObject(obj);//实际上就是调用我们传递进来的状态维护类销毁对象

}

notifyAll(); // _numActive has changed

}

//获取对象池空闲对象数量

public synchronized int getNumIdle() {

assertOpen();

return _pool.size();

}

//获取对象池已被使用的对象数量

public synchronized int getNumActive() {

assertOpen();

return _numActive;

}

//销毁对象池所有对象,并将对象池清空

public synchronized void clear() {

assertOpen();

if(null != _factory) {

Iterator it = _pool.iterator();

while(it.hasNext()) {

try {

_factory.destroyObject(it.next());

} catch(Exception e) {

// ignore error, keep destroying the rest

}

}

}

_pool.clear();

}

//清空对象池,并将对象池状态设置为关闭

public synchronized void close() throws Exception {

clear();

_pool = null;

_factory = null;

super.close();

}

//添加对象

public synchronized void addObject() throws Exception {

assertOpen();

Object obj = _factory.makeObject();//直接调用我们传递的类添加

_numActive++; // A little slimy - must do this because returnObject decrements it.

this.returnObject(obj);

}

//设置对象状态维护工厂

public synchronized void setFactory(PoolableObjectFactory factory) throws IllegalStateException {

assertOpen();

if(0 < getNumActive()) {

throw new IllegalStateException("Objects are already active");

} else {

clear();

_factory = factory;

}

}

}

注意:上面每个方法都是声明为synchronized 的,所以在是线程安全的,在多线程中可以放心使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: