如果一种类型的对象需要经常被创建、销毁,为了提高性能,我们通常需要使用“池”技术,就如线程池、TCP连接池等一样。那么需要使用池技术的对象一般有哪些特征了?
public
interface
IObjectPool

{
//objType为缓存的对象的类型,cArgs为缓存对象的构造参数
boolInitialize(TypeobjType,object[]cArgs,intminNum,intmaxNum);
objectRentObject();
voidGiveBackObject(intobjHashCode);
voidDispose();


intMinObjCount
{get;}

intMaxObjCount
{get;}

intCurObjCount
{get;}

intIdleObjCount
{get;}

eventCallBackObjPoolPoolShrinked;
eventCallBackObjPoolMemoryUseOut;//内存分配失败
}

public
delegate
void
CallBackObjPool();
public
interface
IPooledObjSupporter:IDisposable

{
voidReset();//恢复对象为初始状态,当IObjectPool.GiveBackObject时调用
}
using
System;
using
System.Collections;
using
System.Reflection;

namespace
EnterpriseServerBase.Infrastructure

{

/**////<summary>
///IObjectPool的默认实现。
///作者:朱伟sky.zhuwei@163.com
///</summary>

ObjectPool#regionObjectPool
publicclassObjectPool:IObjectPool


{

members#regionmembers
privateTypedestType=null;
privateobject[]ctorArgs=null;
privateintminObjCount=0;
privateintmaxObjCount=0;
privateintshrinkPoint=0;
privateHashtablehashTableObjs=newHashtable();
privateHashtablehashTableStatus=newHashtable();//key-isIdle其中key就是hashcode
privateArrayListkeyList=newArrayList();
privateboolsupportReset=false;
#endregion


IObjectPool成员#regionIObjectPool成员
publiceventCallBackObjPoolPoolShrinked;
publiceventCallBackObjPoolMemoryUseOut;

publicboolInitialize(TypeobjType,object[]cArgs,intminNum,intmaxNum)


{
if(minNum<1)


{
minNum=1;
}
if(maxNum<5)


{
maxNum=5;
}

this.destType=objType;
this.ctorArgs=cArgs;
this.minObjCount=minNum;
this.maxObjCount=maxNum;
doublecof=1-((double)minNum/(double)maxNum);
this.shrinkPoint=(int)(cof*minNum);

//缓存的类型是否支持IPooledObjSupporter接口
TypesupType=typeof(IPooledObjSupporter);
if(supType.IsAssignableFrom(objType))


{
this.supportReset=true;
}

this.InstanceObjects();

returntrue;
}

privatevoidInstanceObjects()


{
for(inti=0;i<this.minObjCount;i++)


{
this.CreateOneObject();
}
}


CreateOneObject,DistroyOneObject#regionCreateOneObject,DistroyOneObject
privateintCreateOneObject()


{
objectobj=null;

try


{
obj=Activator.CreateInstance(this.destType,this.ctorArgs);
}
catch(Exceptionee)//分配内存失败!


{
ee=ee;
this.maxObjCount=this.CurObjCount;
if(this.minObjCount>this.CurObjCount)


{
this.minObjCount=this.CurObjCount;
}

if(this.MemoryUseOut!=null)


{
this.MemoryUseOut();
}

return-1;
}

intkey=obj.GetHashCode();
this.hashTableObjs.Add(key,obj);
this.hashTableStatus.Add(key,true);
this.keyList.Add(key);

returnkey;
}

privatevoidDistroyOneObject(intkey)


{
objecttarget=this.hashTableObjs[key];
IDisposabletar=targetasIDisposable;
if(tar!=null)


{
tar.Dispose();
}

this.hashTableObjs.Remove(key);
this.hashTableStatus.Remove(key);
this.keyList.Remove(key);
}
#endregion

publicobjectRentObject()


{
lock(this)


{
objecttarget=null;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])//isIdle


{
this.hashTableStatus[key]=false;
target=this.hashTableObjs[key];
break;
}
}

if(target==null)


{
if(this.keyList.Count<this.maxObjCount)


{
intkey=this.CreateOneObject();
if(key!=-1)


{
this.hashTableStatus[key]=false;
target=this.hashTableObjs[key];
}
}
}

returntarget;
}

}


GiveBackObject#regionGiveBackObject
publicvoidGiveBackObject(intobjHashCode)


{
if(this.hashTableStatus[objHashCode]==null)


{
return;
}

lock(this)


{
this.hashTableStatus[objHashCode]=true;
if(this.supportReset)


{
IPooledObjSupportersupporter=(IPooledObjSupporter)this.hashTableObjs[objHashCode];
supporter.Reset();
}

if(this.CanShrink())


{
this.Shrink();
}
}
}

//能够收缩对象池
privateboolCanShrink()


{
intidleCount=this.GetIdleObjCount();
intbusyCount=this.CurObjCount-idleCount;

return(busyCount<this.shrinkPoint)&&(this.CurObjCount>(this.minObjCount+(this.maxObjCount-this.minObjCount)/2));
}

privatevoidShrink()


{
while(this.CurObjCount>this.minObjCount)


{
intdestKey=-1;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])


{
destKey=key;
break;
}
}

if(destKey!=-1)


{
this.DistroyOneObject(destKey);
}
else


{
break;
}
}

if(this.PoolShrinked!=null)


{
this.PoolShrinked();
}
}
#endregion

publicvoidDispose()


{
TypesupType=typeof(System.IDisposable);
if(supType.IsAssignableFrom(this.destType))


{
ArrayListlist=(ArrayList)this.keyList.Clone();
foreach(intkeyinlist)


{
this.DistroyOneObject(key);
}
}

this.hashTableStatus.Clear();
this.hashTableObjs.Clear();
this.keyList.Clear();
}


property#regionproperty
publicintMinObjCount


{
get


{
returnthis.minObjCount;
}
}

publicintMaxObjCount


{
get


{
returnthis.maxObjCount;
}
}

publicintCurObjCount


{
get


{
returnthis.keyList.Count;
}
}

publicintIdleObjCount


{
get


{
lock(this)


{
returnthis.GetIdleObjCount();
}
}
}

privateintGetIdleObjCount()


{
intcount=0;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])


{
++count;
}
}

returncount;
}
#endregion

#endregion
}
#endregion
}
public
interface
IPooledObjSupporter:IDisposable

{
voidReset();//恢复对象为初始状态,当IObjectPool.GiveBackObject时调用
}
using
System;
using
System.Collections;
using
System.Reflection;

namespace
EnterpriseServerBase.Infrastructure

{

/**////<summary>
///IObjectPool的默认实现。
///作者:朱伟sky.zhuwei@163.com
///</summary>

ObjectPool#regionObjectPool
publicclassObjectPool:IObjectPool


{

members#regionmembers
privateTypedestType=null;
privateobject[]ctorArgs=null;
privateintminObjCount=0;
privateintmaxObjCount=0;
privateintshrinkPoint=0;
privateHashtablehashTableObjs=newHashtable();
privateHashtablehashTableStatus=newHashtable();//key-isIdle其中key就是hashcode
privateArrayListkeyList=newArrayList();
privateboolsupportReset=false;
#endregion


IObjectPool成员#regionIObjectPool成员
publiceventCallBackObjPoolPoolShrinked;
publiceventCallBackObjPoolMemoryUseOut;

publicboolInitialize(TypeobjType,object[]cArgs,intminNum,intmaxNum)


{
if(minNum<1)


{
minNum=1;
}
if(maxNum<5)


{
maxNum=5;
}

this.destType=objType;
this.ctorArgs=cArgs;
this.minObjCount=minNum;
this.maxObjCount=maxNum;
doublecof=1-((double)minNum/(double)maxNum);
this.shrinkPoint=(int)(cof*minNum);

//缓存的类型是否支持IPooledObjSupporter接口
TypesupType=typeof(IPooledObjSupporter);
if(supType.IsAssignableFrom(objType))


{
this.supportReset=true;
}

this.InstanceObjects();

returntrue;
}

privatevoidInstanceObjects()


{
for(inti=0;i<this.minObjCount;i++)


{
this.CreateOneObject();
}
}


CreateOneObject,DistroyOneObject#regionCreateOneObject,DistroyOneObject
privateintCreateOneObject()


{
objectobj=null;

try


{
obj=Activator.CreateInstance(this.destType,this.ctorArgs);
}
catch(Exceptionee)//分配内存失败!


{
ee=ee;
this.maxObjCount=this.CurObjCount;
if(this.minObjCount>this.CurObjCount)


{
this.minObjCount=this.CurObjCount;
}

if(this.MemoryUseOut!=null)


{
this.MemoryUseOut();
}

return-1;
}

intkey=obj.GetHashCode();
this.hashTableObjs.Add(key,obj);
this.hashTableStatus.Add(key,true);
this.keyList.Add(key);

returnkey;
}

privatevoidDistroyOneObject(intkey)


{
objecttarget=this.hashTableObjs[key];
IDisposabletar=targetasIDisposable;
if(tar!=null)


{
tar.Dispose();
}

this.hashTableObjs.Remove(key);
this.hashTableStatus.Remove(key);
this.keyList.Remove(key);
}
#endregion

publicobjectRentObject()


{
lock(this)


{
objecttarget=null;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])//isIdle


{
this.hashTableStatus[key]=false;
target=this.hashTableObjs[key];
break;
}
}

if(target==null)


{
if(this.keyList.Count<this.maxObjCount)


{
intkey=this.CreateOneObject();
if(key!=-1)


{
this.hashTableStatus[key]=false;
target=this.hashTableObjs[key];
}
}
}

returntarget;
}

}


GiveBackObject#regionGiveBackObject
publicvoidGiveBackObject(intobjHashCode)


{
if(this.hashTableStatus[objHashCode]==null)


{
return;
}

lock(this)


{
this.hashTableStatus[objHashCode]=true;
if(this.supportReset)


{
IPooledObjSupportersupporter=(IPooledObjSupporter)this.hashTableObjs[objHashCode];
supporter.Reset();
}

if(this.CanShrink())


{
this.Shrink();
}
}
}

//能够收缩对象池
privateboolCanShrink()


{
intidleCount=this.GetIdleObjCount();
intbusyCount=this.CurObjCount-idleCount;

return(busyCount<this.shrinkPoint)&&(this.CurObjCount>(this.minObjCount+(this.maxObjCount-this.minObjCount)/2));
}

privatevoidShrink()


{
while(this.CurObjCount>this.minObjCount)


{
intdestKey=-1;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])


{
destKey=key;
break;
}
}

if(destKey!=-1)


{
this.DistroyOneObject(destKey);
}
else


{
break;
}
}

if(this.PoolShrinked!=null)


{
this.PoolShrinked();
}
}
#endregion

publicvoidDispose()


{
TypesupType=typeof(System.IDisposable);
if(supType.IsAssignableFrom(this.destType))


{
ArrayListlist=(ArrayList)this.keyList.Clone();
foreach(intkeyinlist)


{
this.DistroyOneObject(key);
}
}

this.hashTableStatus.Clear();
this.hashTableObjs.Clear();
this.keyList.Clear();
}


property#regionproperty
publicintMinObjCount


{
get


{
returnthis.minObjCount;
}
}

publicintMaxObjCount


{
get


{
returnthis.maxObjCount;
}
}

publicintCurObjCount


{
get


{
returnthis.keyList.Count;
}
}

publicintIdleObjCount


{
get


{
lock(this)


{
returnthis.GetIdleObjCount();
}
}
}

privateintGetIdleObjCount()


{
intcount=0;
foreach(intkeyinthis.keyList)


{
if((bool)this.hashTableStatus[key])


{
++count;
}
}

returncount;
}
#endregion

#endregion
}
#endregion
}
(1)创建过程耗时
(2)不需要保存客户状态
(3)对象体积较大
(4)频繁创建/销毁
为了省事,我希望实现一个万能对象池组件,该对象池可以缓存任意类型的对象。下面给出对象池的接口:




























上面接口中的各个方法的含义很清楚。其中PoolShrinked表示池中的对象个数有Max变为Min。
我们可以考虑这样一种情况,当我们需要缓存的对象需要维持和一个客户之间的状态,那么也是可以的,如果是这样,所缓存的类型最好实现下面的IPooledObjSupporter接口。






对象在实现该接口后,就可以被对象池在收到归还的对象时重置其状态了。整个对象池的实现代码如下:














































































































































































































































































































































































































对象在实现该接口后,就可以被对象池在收到归还的对象时重置其状态了。整个对象池的实现代码如下:







































































































































































































































































































































































































