用C#建立通用对象池[2]
来源:互联网 发布:生物为什么要繁衍 知乎 编辑:程序博客网 时间:2024/05/22 15:55
创建一个接口,用于限定对象池中所保存的对象的基本行为:
public interface IDynamicObject
{
void Create(Object param);
Object GetInnerObject();
bool IsValidate();
void Release();
}
我们在对象池中存放的对象,必须继承上面的接口,并实现接口定义的每一个方法。
Create方法中,用户可以用来创建实际的对象,如建立数据库连接,并打开这个连接;GetInnerObject方法,使用户可以返回这个实际的对象,如一个SqlConnection对象;IsValidate方法是用来判断用户自定义对象的有效性的,是对象池决定是否重新创建对象的标志;Release方法中,用户可以进行资源释放工作。
有了上面的接口定义,为我们可以在列表中保存用户自定义对象打下了基础。下面就是要实现这个ObjectPool了。
用户自定义对象在我们的ObjectPool中,可以用列表存储,如ArrayList或者Hashtable,为了表示每个用户对象的状态,我们还需要将用户自定义对象包装一下,然后在放到列表中保存。下面定义了一个ObjectPool类的子类,用于包装用户自定义对象:
private class PoolItem
{
private IDynamicObject _object;
private bool _bUsing;
private Type _type;
private Object _CreateParam;
public PoolItem(Type type,Object param)
{
_type = type;
_CreateParam = param;
Create();
}
private void Create()
{
_bUsing = false;
_object = (IDynamicObject)System.Activator.CreateInstance(_type);
_object.Create(_CreateParam);
}
public void Recreate()
{
_object.Release();
Create();
}
public void Release()
{
_object.Release();
}
public Object InnerObject
{
get{return _object.GetInnerObject();}
}
public int InnerObjectHashcode
{
get{return InnerObject.GetHashCode();}
}
public bool IsValidate
{
get{return _object.IsValidate();}
}
public bool Using
{
get{return _bUsing;}
set
{
_bUsing = value;
}
}
}// class PoolItem
这个类,一个关键的属性是Using,该属性表示对象是否正在被被用户使用。注意,PoolItem创建时,接受一个Object类型的Param参数,这个参数最后被传递给用户自定义对象的Create方法。用户可以利用这一点,在创建ObjectPool时指定一些参数,供其自定义对象在创建时使用。比如创建SocketPool时,将服务器IP,端口通过Param传递给自定义对象的Create方法,用户就可以在Create方法中连接指定的服务器了。
以下是ObjectPool的具体实现代码:
public sealed class ObjectPool
{
private Int32 _nCapacity;
private Int32 _nCurrentSize;
private Hashtable _listObjects; private ArrayList _listFreeIndex;
private ArrayList _:listUsingIndex;
private Type _typeObject;
private Object _objCreateParam;
public ObjectPool(Type type, Object create_param, Int32 init_size, Int32 capacity)
{
if(init_size < 0 || capacity < 1 || init_size>capacity)
{
throw(new Exception("Invalid parameter!"));
}
_nCapacity = capacity;
_listObjects = new Hashtable(capacity);
_listFreeIndex = new ArrayList(capacity);
_listUsingIndex = new ArrayList(capacity);
_typeObject = type;
_objCreateParam = create_param;
for(int i=0;i<init_size;i++)
{
PoolItem pitem = new PoolItem(type,create_param);
_listObjects.Add(pitem.InnerObjectHashcode,pitem);
_listFreeIndex.Add(pitem.InnerObjectHashcode);
}
_nCurrentSize = _listObjects.Count;
}
public void Release()
{
lock(this)
{
foreach(DictionaryEntry de in _listObjects)
{
( (PoolItem)de.Value ).Release();
}
_listObjects.Clear();
_listFreeIndex.Clear();
_listUsingIndex.Clear();
}
}
public Int32 CurrentSize
{
get{return _nCurrentSize;}
}
public Int32 ActiveCount
{
get{return _listUsingIndex.Count;}
}
public Object GetOne()
{
lock(this)
{
if(_listFreeIndex.Count == 0)
{
if(_nCurrentSize == _nCapacity)
{
return null;
}
PoolItem pnewitem = new PoolItem(_typeObject,_objCreateParam);
_listObjects.Add(pnewitem.InnerObjectHashcode,pnewitem);
_listFreeIndex.Add(pnewitem.InnerObjectHashcode);
_nCurrentSize++;
}
Int32 nFreeIndex = (Int32)_listFreeIndex[0];
PoolItem pitem = (PoolItem)_listObjects[nFreeIndex];
_listFreeIndex.RemoveAt(0);
_listUsingIndex.Add(nFreeIndex);
if(!pitem.IsValidate)
{
pitem.Recreate();
}
pitem.Using = true;
return pitem.InnerObject;
}
}
public void FreeObject(Object obj)
{
lock(this)
{
int key = obj.GetHashCode();
if(_listObjects.ContainsKey(key))
{
PoolItem item = (PoolItem)_listObjects[key];
item.Using = false;
_listUsingIndex.Remove(key);
_listFreeIndex.Add(key);
}
}
}
public Int32 DecreaseSize(Int32 size)
{
Int32 nDecrease = size;
lock(this)
{
if(nDecrease <= 0)
{
return 0;
}
if(nDecrease > _listFreeIndex.Count)
{
nDecrease = _listFreeIndex.Count;
}
for(int i=0;i<nDecrease;i++)
{
_listObjects.Remove(_listFreeIndex[i]);
}
_listFreeIndex.Clear();
_listUsingIndex.Clear();
foreach(DictionaryEntry de in _listObjects)
{
PoolItem pitem = (PoolItem)de.Value;
if(pitem.Using)
{
_listUsingIndex.Add(pitem.InnerObjectHashcode);
}
else
{
_listFreeIndex.Add(pitem.InnerObjectHashcode);
}
}
}
_nCurrentSize -= nDecrease;
return nDecrease;
}
}
下篇再给出一个用这个ObjectPool实现的数据库连接池的例子。
- 用C#建立通用对象池[2]
- 用C#建立通用对象池[1]
- 用C#建立通用对象池[3]
- 用C#建立通用对象池
- 用C#建立通用对象池
- 通用方法:用建立Excel对象的方法来导出数据
- 通用对象池
- 用C#建立数据库连接池
- C/C++通用面向对象接口
- Unity中的通用对象池
- Unity中的通用对象池
- c++---对象的动态建立和释放
- 用Java实现一个通用并发对象池
- 用Java实现一个通用并发对象池
- Arrays and generics 数组和通用 不能建立对象的几种实现
- [C++] 通用算法、函数对象、lambda表达式、bind
- 建立对象
- 一个通用并发对象池的实现
- 10g improved vldb
- Weblogic & Oracle体系结构与技术要点
- 重读《Essential C++》心得
- 对XML文档操作的通用CRUD(JDOM版)
- 测试Java代码的执行时间
- 用C#建立通用对象池[2]
- 运行数据库statspack一天分析(备忘)
- 源码公开的TCP/IP协议栈在远程监测中的应用
- 十年MFC经历认识的Microsoft技术(zz)
- windows下快速安装可以通过http和https访问的subversion服务器
- 绝不妥协
- dbms_resumable
- 丢了就再也找不回来了!
- 求助Delphi的入门教程