對象池模式

對象池模式

對象池模式(The Object Pool Pattern)是單例模式的一個變種,它提供了獲取一系列相同對象實例的入口。當你需要對象來代表一組可替代資源的時候就變的很有用,每個對象每次可以被一個組件使用。

基本介紹

  • 中文名:對象池模式
  • 外文名:The Object Pool Pattern
  • 屬於單例模式
  • 意義:提供獲取相同對象實例的入口
  • 優點:沒有釋放記憶體
  • 缺點:池中對象的數量有限
舉例,理解方法,優點,缺點,套用,

舉例

在許多項目中,有時候對象的實例數目可能會有限制。請看下面例子:
舉例舉例
在一個追蹤圖書館書的系統中,創建或者克隆Book對象都不適用於現實中的圖書館中的書。同樣的如果使用單例模式也不行,因為圖書館裡可不止一本書。
圖書管中的每一本書都有可能在某個時候被讀者借出並且以後不能再被人使用直到歸還。當書在庫的時候讀者可以立即借出,但是當庫存耗盡的時候,任何想要再借這本書的人都必須等到某個人還書或者圖書館增加庫存。

理解方法

對象池模式管理一個可代替對象的集合。組件從池中借出對象,用它來完成一些任務並當任務完成時歸還該對象。被歸還的對象接著滿足請求,不管是同一個組件還是其他組件的請求。對象池模式可以管理那些代表的現實資源或者通過重用來分攤昂貴初始化代價的對象。
理解方法理解方法
第二步操作就是借出。
第三步操作是組件用借出的對象來完成一些任務。這時候並不需要對象池再做什麼,但是這也意味著該對象將被租借一段時間並且不能在被其他組件借出。
第四步操作就是歸還,組件歸還借出的對象這樣可以繼續滿足其他的租借請求。
在一個多執行緒的套用中,第二,第三,第四步操作都有可能發生並發操作。多執行緒的組件中分享對象導致了潛在的並發問題。也存在一種情況就是當所有對象都被借出時不能滿足接下來的請求,對象池必須應對這些請求,不管是告訴組件已經沒有對象可借還是允許組件等待直到有歸還的對象。

優點

復用池中對象,沒有分配記憶體和創建堆中對象的開銷, 沒有釋放記憶體和銷毀堆中對象的開銷, 進而減少垃圾收集器的負擔, 避免記憶體抖動;不必重複初始化對象狀態, 對於比較耗時的constructor和finalize來說非常合適;

缺點

(1)現在Java的對象分配操作不比c語言的malloc調用慢, 對於輕中量級的對象, 分配/釋放對象的開銷可以忽略不計;
(2)並發環境中, 多個執行緒可能(同時)需要獲取池中對象, 進而需要在堆數據結構上進行同步或者因為鎖競爭而產生阻塞, 這種開銷要比創建銷毀對象的開銷高數百倍;
(3)由於池中對象的數量有限, 勢必成為一個可伸縮性瓶頸;
(4)很難正確的設定對象池的大小, 如果太小則起不到作用, 如果過大, 則占用記憶體資源高, 可以起一個執行緒定期掃描分析, 將池壓縮到一個合適的尺寸以節約記憶體,但為了獲得不錯的分析結果, 在掃描期間可能需要暫停復用以避免干擾(造成效率低下), 或者使用非常複雜的算法策略(增加維護難度);
(5)設計和使用對象池容易出錯, 設計上需要注意狀態同步, 這是個難點, 使用上可能存在忘記歸還(就像c語言編程忘記free一樣), 重複歸還(可能需要做個循環判斷一下是否池中存在此對象, 這也是個開銷), 歸還後仍舊使用對象(可能造成多個執行緒並發使用一個對象的情況)等問題。

套用

對象池模式經常用在頻繁創建、銷毀對象(並且對象創建、銷毀開銷很大)的場景,比如資料庫連線池、執行緒池、任務佇列池等。

相關詞條

熱門詞條

聯絡我們