Java對象池pool2分析PooledObjectFactory過程
背景
池化技術(shù) 在Java中使用的相當多了,例如各種數(shù)據(jù)庫連接池,以及JDK自己實現(xiàn)的線程池等等,從根本上說他們都是對象池,把資源池化,按需存取,不僅能夠一定程度上節(jié)省對象的創(chuàng)建時間(緩存思想),還能夠?qū)Τ刈幼鲆恍┕芾砗涂刂?例如設(shè)置資源最大數(shù),閑置數(shù)等等)。
池的經(jīng)典實現(xiàn)要數(shù) apache 的 pool2 了 .
Pool2
默認的對象池是 GenericObjectPool
通過最核心的 borrowObject 和 returnObject 方法進行對象的取和歸還。
但是在 GenericObjectPool 的構(gòu)造函數(shù)中有兩個參數(shù)。
GenericObjectPool<MyObject> objectPool = new GenericObjectPool<>(new MyPooledObjectFactory(),new GenericObjectPoolConfig());
其中第二個是GenericObjectPoolConfig
類,里面是關(guān)于Pool的一些配置,例如最大資源數(shù),最大,最小閑置數(shù)。它繼承了BaseObjectPoolConfig
類,里面有關(guān)于空閑資源的清理策略,資源爭奪屬性,等待超時時間等等很多復(fù)雜的屬性,詳見源碼。
這里主要說的是第一個參數(shù) PooledObjectFactory ,他是唯一需要我們自己去實現(xiàn)的地方,很明顯是一個工廠,用于 生產(chǎn),銷毀,激活,驗證 我們的池化資源對象。
注意:
放入池中的資源被包裝成了 PooledObject 類型的對象,之所以包裝,是因為向其中添加了很多屬性,例如資源對象的狀態(tài),等待時間,閑置時間,最后一次使用的時間,借出次數(shù)等等屬性。類似于JDK線程池放入的 Runnble對象會被包裝成Worker對象一樣。
這里以商場里的共享充電寶為例,這個簡單來說就是一個池化的思維。
每個充電寶只有一個屬性,那就是剩余電量。用于模擬,只有一個方法,就是借出去被使用。
那么我們需要自己實現(xiàn)的 PooledObjectFactory 可以是:
- 第一個 makeObject 方法 :用于對象的新建,一般是 new 出來之后包裝一下。而什么時候需要新建呢,根據(jù)策略不同則時機不同。例如在沒有閑置資源對象,且已存在的資源數(shù)不超過所設(shè)置的最大資源時新建。
- 第二個 destroyObject 方法:銷毀一個對象,除了很容易想到的閑置過長時間被清理掉了導(dǎo)致需要銷毀之外,還有如果進行了第三個方法且返回了 false ,那么也是需要銷毀的。
- 第三個 validateObject方法:檢驗這個對象是否還有有效,借出和歸還時,以及內(nèi)置后臺線程檢測閑置情況時,可以通過驗證可以去除一些不符合業(yè)務(wù)邏輯的資源對象。默認這個方法是不被調(diào)用的,要開啟則需要在PoolConfig中設(shè)置setTestOnBorrow , setTestOnReturn , setTestWhileIdle等屬性。
第一個 activeObject 方法: 在借用一個對象的時候調(diào)用,則可以在此重置其內(nèi)部狀態(tài),那么返回的對象就像新的一樣,例如這里重置電量
第一個 passivateObject 方法: 對應(yīng) activateObject 方法,是在歸還一個對象的時候調(diào)用,注意不應(yīng)與activateObject方法有業(yè)務(wù)邏輯上的沖突
用于測試的主函數(shù):
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot使用PropertiesLauncher加載外部jar包
這篇文章主要介紹了SpringBoot使用PropertiesLauncher加載外部jar包,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07Java concurrency集合之ConcurrentHashMap_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了Java concurrency集合之ConcurrentHashMap的相關(guān)資料,需要的朋友可以參考下2017-06-06jdk8?FunctionalInterface注解源碼解讀
這篇文章主要介紹了jdk8?FunctionalInterface注解源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11idea中將單個java類導(dǎo)出為jar包文件的方法
這篇文章主要給大家介紹了關(guān)于idea中將單個java類導(dǎo)出為jar包文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Java多線程編程基石ThreadPoolExecutor示例詳解
這篇文章主要為大家介紹了Java多線程編程基石ThreadPoolExecutor示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04