对象池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 的,所以在是线程安全的,在多线程中可以放心使用。
该包所有的类与接口不多,也就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 的,所以在是线程安全的,在多线程中可以放心使用。
相关文章推荐
- 对象池commons-pool框架的研究以及源代码分析(五)
- 对象池commons-pool框架的研究以及源代码分析(三)
- 对象池commons-pool框架的研究以及源代码分析(六)总结
- 对象池commons-pool框架的研究以及源代码分析(一)
- 对象池commons-pool框架的研究以及源代码分析(四)
- 数据库连接池DBCP框架的研究以及源代码分析三:打开AbandonedObjectPool连接池
- 数据库连接池DBCP框架的研究以及源代码分析一:第一个DBCP例子
- 数据库连接池DBCP框架的研究以及源代码分析二:寻找真正的DataSource
- php框架codeigniter框架源代码分析,注释中文化,类库分析(一)
- 写了几年代码了,苦苦追寻,应该沉淀下来了,好好研究。net底层框架,以及较好的分层框架
- 分析 JUnit 框架源代码
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
- 分享一个简易的ORM框架源代码以及基于该框架开发的一个简易论坛源代码
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现(自然排序)
- 对SSI框架,Struts2页面标签以及JQuery表单提交的分析
- 分析 JUnit 框架源代码
- IOS框架研究之SDWebImage的原理以及使用流程
- boost::any的用法、优点和缺点以及源代码分析
- boost::any的用法、优点和缺点以及源代码分析