C 物件池詳細解析

2021-08-31 02:50:59 字數 4043 閱讀 8240

在系統設計中,經常會使用「池」的概念。比如資料庫連線池,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 物件池實現

在實際中,我們會遇到乙個類最多隻允許若干個物件同時存在的情形。如果這個類的物件會被頻繁的建立,使用並銷毀,那這時會對系統效能造成影響,而這時可以考慮使用物件池的方法來避免每次使用物件都需要從 構造 使用 銷毀 這個流程,物件池中的每個物件都一次構造多次使用,而析構也只會在物件池析構是才會發生。要實現...