Apache Commons Pool2 源碼分析 | Apache Commons Pool2 Source Code Analysis


Apache Commons Pool實現了對象池的功能。定義了對象的生成、銷毀、激活、鈍化等操作及其狀態轉換,並提供幾個默認的對象池實現。
在講述其實現原理前,先提一下其中有幾個重要的對象:

  • PooledObject(池對象)。
  • PooledObjectFactory(池對象工廠)。
  • Object Pool(對象池)。

下面分別詳細講解它們的實現。

PooledObject(池對象)

用於封裝對象(如:線程、數據庫連接、TCP連接),將其包裹成可被池管理的對象。提供了兩個默認的池對象實現:
  • DefaultPoolObject。用於非軟引用的普通對象。
  • PooledSoftReference。用於軟引用的對象。
在開發連接池、線程池等組件時,需要根據實際情況重載5個方法:startEvictionTest、endEvictionTest、allocate、deallocate和invalidate,用於在不同的場景下修改被包裹對象的內部狀態。
Apache Commons Pool 源碼分析 | Apache Commons Pool Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 

PooledObject有多種狀態,在不同的環節或經過處理后狀態會發生變化。

狀態 描述
IDLE 位於隊列中,未使用
ALLOCATED 在使用
EVICTION 位於隊列中,當前正在測試,可能會被回收
EVICTION_RETURN_TO_HEAD 不在隊列中,當前正在測試,可能會被回收。從池中借出對象時需要從隊列出移除並進行測試
VALIDATION 位於隊列中,當前正在驗證
VALIDATION_PREALLOCATION 不在隊列中,當前正在驗證。當對象從池中被借出,在配置了testOnBorrow的情況下,對像從隊列移除和進行預分配的時候會進行驗證
VALIDATION_RETURN_TO_HEAD 不在隊列中,正在進行驗證。從池中借出對象時,從隊列移除對象時會先進行測試。返回到隊列頭部的時候應該做一次完整的驗證
INVALID 回收或驗證失敗,將銷毀
ABANDONED 即將無效
RETURN 返還到池中
 
根據Apache Commons Pool2的默認實現,其狀態變化如下圖所示:
Apache Commons Pool2 源碼分析 | Apache Commons Pool2 Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 

PooledObjectFactory(池對象工廠)

定義了操作PooledObject實例生命周期的一些方法,PooledObjectFactory必須實現線程安全。已經有兩個抽象工廠:
  • BasePooledObjectFactory。
  • BaseKeyedPooledObjectFactory。
直接繼承它們實現自己的池對象工廠。
Apache Commons Pool 源碼分析 | Apache Commons Pool Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 
方法 描述
makeObject 用於生成一個新的ObjectPool實例
activateObject 每一個鈍化(passivated)的ObjectPool實例從池中借出(borrowed)前調用
validateObject 可能用於從池中借出對象時,對處於激活(activated)狀態的ObjectPool實例進行測試確保它是有效的。也有可能在ObjectPool實例返還池中進行鈍化前調用進行測試是否有效。它只對處於激活狀態的實例調用
passivateObject 當ObjectPool實例返還池中的時候調用
destroyObject 當ObjectPool實例從池中被清理出去丟棄的時候調用(是否根據validateObject的測試結果由具體的實現在而定)
 

Object Pool (對象池)

Object Pool負責管理PooledObject,如:借出對象,返回對象,校驗對象,有多少激活對象,有多少空閑對象。有三個默認的實現類:
  • GenericObjectPool。
  • ProsiedObjectPool。
  • SoftReferenceObjectPool。
Apache Commons Pool 源碼分析 | Apache Commons Pool Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 
方法 描述
borrowObject 從池中借出一個對象。要么調用PooledObjectFactory.makeObject方法創建,要么對一個空閑對象使用PooledObjectFactory.activeObject進行激活,然后使用PooledObjectFactory.validateObject方法進行驗證后再返回
returnObject 將一個對象返還給池。根據約定:對象必須 是使用borrowObject方法從池中借出的
invalidateObject 廢棄一個對象。根據約定:對象必須 是使用borrowObject方法從池中借出的。通常在對象發生了異常或其他問題時使用此方法廢棄它
addObject 使用工廠創建一個對象,鈍化並且將它放入空閑對象池
getNumberIdle 返回池中空閑的對象數量。有可能是池中可供借出對象的近似值。如果這個信息無效,返回一個負數
getNumActive 返回從借出的對象數量。如果這個信息不可用,返回一個負數
clear 清除池中的所有空閑對象,釋放其關聯的資源(可選)。清除空閑對象必須使用PooledObjectFactory.destroyObject方法
close 關閉池並釋放關聯的資源
 

BorrowObject (借出對象)

下面是GenericObjectPool中borrowObject方法的邏輯實現,有阻塞式和非阻塞式兩種獲取對象的模式。
Apache Commons Pool2 源碼分析 | Apache Commons Pool2 Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 

ReturnObject (返還對象)

下面是GenericObjectPool中returnObject方法的邏輯實現,在這里實現的FIFO(先進先出)和LIFO(后進先出)。
Apache Commons Pool2 源碼分析 | Apache Commons Pool2 Source Code Analysis - 傲風 - 0與1構築世界,程序員創造時代
 

參考資料

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM