在系統設計中,經常會使用「池」的概念。比如資料庫連線池,socket連線池,執行緒池,元件佇列。「池」可以節省物件重複建立和初始化所耗費 的時間,可以簡化物件獲取和使用的過程。對於那些被系統頻繁請求和使用的物件,如果使用這種機制,可以使系統效能得到很大提高。特別象資料庫連線這種對 象,客戶端與資料庫伺服器端建立連線時,是比較慢的,如果每次進行資料庫操作,都要先進行資料庫連線,系統效率將非常低下。 powered by 25175.net
「池」的概念就是將被使用的物件事先建立好,儲存在列表中,供客戶端取用。當客戶端取得乙個物件時,這個物件就已經是按照特定上下文環境初始化好,馬上即 可使用的了。當客戶端使用完畢,需要將物件歸還給「池」,最後,在系統生命期結束時,由「池」統一釋放這些物件。從另乙個概念上來說,這也是一種「以空間 換時間」的做法,我們在記憶體中儲存一系列整裝待命的物件,供人隨時差遣。與系統效率相比,這些物件所占用的記憶體空間太微不足道了。
「池」的結構是通用的,就是不管他裡面儲存的是哪一種物件,他的工作方法都基本不變。無非是初始化一系列物件,然後提供乙個獲取可用物件,乙個歸還物件的介面。
基於這種考慮,我們可以建立乙個通用的物件池,只要某些物件符合「一些基本要求」(這個基本要求,可以使用inte***ce模式來限定),就可以使用通用物件池來訪問和管理。
建立乙個介面,用於限定物件池中所儲存的物件的基本行為:
複製c#**儲存**public inte***ce idynamicobject
我們在物件池中存放的物件,必須繼承上面的介面,並實現介面定義的每乙個方法。
create方法中,使用者可以用來建立實際的物件,如建立資料庫連線,並開啟這個連線;getinnerobject方法,使使用者可以返回這個實際 的物件,如乙個sqlconnection物件;isvalidate方法是用來判斷使用者自定義物件的有效性的,是物件池決定是否重新建立物件的標誌; release方法中,使用者可以進行資源釋放工作。
有了上面的介面定義,為我們可以在列表中儲存使用者自定義物件打下了基礎。下面就是要實現這個objectpool了。
使用者自定義物件在我們的objectpool中,可以用列表儲存,如arraylist或者hashtable,為了表示每個使用者物件的狀態,我們 還需要將使用者自定義物件包裝一下,然後在放到列表中儲存。下面定義了乙個objectpool類的子類,用於包裝使用者自定義物件:
複製c#**儲存**private class poolitem
private void create()
public void recreate()
public void release()
public object innerobject }
public int innerobjecthashcode }
public bool isvalidate }
public bool using
set
} }// class poolitem
這個類,乙個關鍵的屬性是using,該屬性表示物件是否正在被被使用者使用。注意,poolitem建立時,接受乙個object型別的param參 數,這個引數最後被傳遞給使用者自定義物件的create方法。使用者可以利用這一點,在建立objectpool時指定一些引數,供其自定義物件在建立時使 用。比如建立socketpool時,將伺服器ip,埠通過param傳遞給自定義物件的create方法,使用者就可以在create方法中連線指定的 伺服器了。powered by 25175.net
以下是objectpool的具體實現**:
複製c#**儲存**public sealed class objectpool
_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++)
_ncurrentsize = _listobjects.count;
}public void release()
_listobjects.clear();
_listfreeindex.clear();
_listusingindex.clear(); } }
public int32 currentsize }
public int32 activecount }
public object getone()
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.using = true;
return pitem.innerobject; } }
public void freeobject(object obj) }
}public int32 decreasesize(int32 size)
if (ndecrease > _listfreeindex.count)
for (int i = 0; i < ndecrease; i++)
_listfreeindex.clear();
_listusingindex.clear();
foreach (dictionaryentry de in _listobjects)
else }
} _ncurrentsize -= ndecrease;
return ndecrease; } }
雖然.net對資料庫連線已經提供了連線池,但是,經測試,使用上述通用物件池實現的資料庫連線池,效率要比直接使用.net管理的連線池高。因為他減少了open和close操作,從而節省了時間。
**如下:
複製c#**儲存**public class dbpool
#region idynamicobject members
public void create(object param)
public object getinnerobject()
public bool isvalidate()
public void release()
#endregion
}private objectpool _connections;
public dbpool(string connection, int initcount, int capacity)
_connections = new objectpool(typeof(sqlconnectionobject), connection, initcount, capacity);
}public sqlconnection getconnection()
public void freeconnection(sqlconnection sqlconn)
public void release()
public int count }
public int usingcount }
public int decreasesize(int size)
} // dbpool
C 物件池詳細解析
在系統設計中,經常會使用 池 的概念。比如資料庫連線池,socket連線池,執行緒池,元件佇列。池 可以節省物件重複建立和初始化所耗費 的時間,可以簡化物件獲取和使用的過程。對於那些被系統頻繁請求和使用的物件,如果使用這種機制,可以使系統效能得到很大提高。特別象資料庫連線這種對 象,客戶端與資料庫伺...
C 中的物件陣列詳細解析
類是物件的抽象,我們可以使用乙個類來定義很多的物件,然後每個物件都有自己的屬性。當我們使用類來定義很多相同結構的物件的時候,我們可以採取物件陣列的方法。例如,乙個班有50個學生,我們定義了乙個學生類,該類的學生具有相同的資料成員和成員函式,我們就可以定義乙個這樣的陣列。複製 如下 student s...
C 物件池實現
在實際中,我們會遇到乙個類最多隻允許若干個物件同時存在的情形。如果這個類的物件會被頻繁的建立,使用並銷毀,那這時會對系統效能造成影響,而這時可以考慮使用物件池的方法來避免每次使用物件都需要從 構造 使用 銷毀 這個流程,物件池中的每個物件都一次構造多次使用,而析構也只會在物件池析構是才會發生。要實現...