Apache Commons Pool
實現了對象池
的功能。定義了對象的生成、銷毀、激活、鈍化等操作及其狀態轉換,並提供幾個默認的對象池實現。
在講述其實現原理前,先提一下其中有幾個重要的對象:
- PooledObject(池對象)。
- PooledObjectFactory(池對象工廠)。
- Object Pool(對象池)。
下面分別詳細講解它們的實現。
PooledObject(池對象)
用於封裝對象(如:線程、數據庫連接、TCP連接),將其包裹成可被池管理的對象。提供了兩個默認的池對象實現:
- DefaultPoolObject。用於非軟引用的普通對象。
- PooledSoftReference。用於軟引用的對象。
在開發連接池、線程池等組件時,需要根據實際情況重載5個方法:startEvictionTest、endEvictionTest、allocate、deallocate和invalidate,用於在不同的場景下修改被包裹對象的內部狀態。
PooledObject有多種狀態
,在不同的環節或經過處理后狀態會發生變化。
狀態 | 描述 |
IDLE | 位於隊列中,未使用 |
ALLOCATED | 在使用 |
EVICTION | 位於隊列中,當前正在測試,可能會被回收 |
EVICTION_RETURN_TO_HEAD | 不在隊列中,當前正在測試,可能會被回收。從池中借出對象時需要從隊列出移除並進行測試 |
VALIDATION | 位於隊列中,當前正在驗證 |
VALIDATION_PREALLOCATION | 不在隊列中,當前正在驗證。當對象從池中被借出,在配置了testOnBorrow的情況下,對像從隊列移除和進行預分配的時候會進行驗證 |
VALIDATION_RETURN_TO_HEAD | 不在隊列中,正在進行驗證。從池中借出對象時,從隊列移除對象時會先進行測試。返回到隊列頭部的時候應該做一次完整的驗證 |
INVALID | 回收或驗證失敗,將銷毀 |
ABANDONED | 即將無效 |
RETURN | 返還到池中 |
根據Apache Commons Pool2的默認實現,其狀態變化如下圖所示:
PooledObjectFactory(池對象工廠)
定義了操作
PooledObject
實例生命周期的一些方法,PooledObjectFactory
必須實現線程安全。已經有兩個抽象工廠:
- BasePooledObjectFactory。
- BaseKeyedPooledObjectFactory。
直接繼承它們實現自己的池對象工廠。
方法 | 描述 |
makeObject | 用於生成一個新的ObjectPool實例 |
activateObject | 每一個鈍化(passivated)的ObjectPool實例從池中借出(borrowed)前調用 |
validateObject | 可能用於從池中借出對象時,對處於激活(activated)狀態的ObjectPool實例進行測試確保它是有效的。也有可能在ObjectPool實例返還池中進行鈍化前調用進行測試是否有效。它只對處於激活狀態的實例調用 |
passivateObject | 當ObjectPool實例返還池中的時候調用 |
destroyObject | 當ObjectPool實例從池中被清理出去丟棄的時候調用(是否根據validateObject的測試結果由具體的實現在而定) |
Object Pool (對象池)
Object Pool
負責管理PooledObject,如:借出對象,返回對象,校驗對象,有多少激活對象,有多少空閑對象。有三個默認的實現類:
- GenericObjectPool。
- ProsiedObjectPool。
- SoftReferenceObjectPool。
方法 | 描述 |
borrowObject | 從池中借出一個對象。要么調用PooledObjectFactory.makeObject方法創建,要么對一個空閑對象使用PooledObjectFactory.activeObject進行激活,然后使用PooledObjectFactory.validateObject方法進行驗證后再返回 |
returnObject | 將一個對象返還給池。根據約定:對象必須 是使用borrowObject方法從池中借出的 |
invalidateObject | 廢棄一個對象。根據約定:對象必須 是使用borrowObject方法從池中借出的。通常在對象發生了異常或其他問題時使用此方法廢棄它 |
addObject | 使用工廠創建一個對象,鈍化並且將它放入空閑對象池 |
getNumberIdle | 返回池中空閑的對象數量。有可能是池中可供借出對象的近似值。如果這個信息無效,返回一個負數 |
getNumActive | 返回從借出的對象數量。如果這個信息不可用,返回一個負數 |
clear | 清除池中的所有空閑對象,釋放其關聯的資源(可選)。清除空閑對象必須使用PooledObjectFactory.destroyObject方法 |
close | 關閉池並釋放關聯的資源 |
BorrowObject (借出對象)
ReturnObject (返還對象)
參考資料
http://aofengblog.blog.163.com/blog/static/6317021201463075826473/
http://commons.apache.org/proper/commons-pool/
http://commons.apache.org/proper/commons-pool/download_pool.cgi