Java對(duì)象池pool2分析PooledObjectFactory過(guò)程
背景
池化技術(shù) 在Java中使用的相當(dāng)多了,例如各種數(shù)據(jù)庫(kù)連接池,以及JDK自己實(shí)現(xiàn)的線程池等等,從根本上說(shuō)他們都是對(duì)象池,把資源池化,按需存取,不僅能夠一定程度上節(jié)省對(duì)象的創(chuàng)建時(shí)間(緩存思想),還能夠?qū)Τ刈幼鲆恍┕芾砗涂刂?例如設(shè)置資源最大數(shù),閑置數(shù)等等)。
池的經(jīng)典實(shí)現(xiàn)要數(shù) apache 的 pool2 了 .
Pool2
默認(rèn)的對(duì)象池是 GenericObjectPool
通過(guò)最核心的 borrowObject 和 returnObject 方法進(jìn)行對(duì)象的取和歸還。

但是在 GenericObjectPool 的構(gòu)造函數(shù)中有兩個(gè)參數(shù)。
GenericObjectPool<MyObject> objectPool = new GenericObjectPool<>(new MyPooledObjectFactory(),new GenericObjectPoolConfig());
其中第二個(gè)是GenericObjectPoolConfig類,里面是關(guān)于Pool的一些配置,例如最大資源數(shù),最大,最小閑置數(shù)。它繼承了BaseObjectPoolConfig類,里面有關(guān)于空閑資源的清理策略,資源爭(zhēng)奪屬性,等待超時(shí)時(shí)間等等很多復(fù)雜的屬性,詳見(jiàn)源碼。
這里主要說(shuō)的是第一個(gè)參數(shù) PooledObjectFactory ,他是唯一需要我們自己去實(shí)現(xiàn)的地方,很明顯是一個(gè)工廠,用于 生產(chǎn),銷毀,激活,驗(yàn)證 我們的池化資源對(duì)象。
注意:
放入池中的資源被包裝成了 PooledObject 類型的對(duì)象,之所以包裝,是因?yàn)橄蚱渲刑砑恿撕芏鄬傩?,例如資源對(duì)象的狀態(tài),等待時(shí)間,閑置時(shí)間,最后一次使用的時(shí)間,借出次數(shù)等等屬性。類似于JDK線程池放入的 Runnble對(duì)象會(huì)被包裝成Worker對(duì)象一樣。
這里以商場(chǎng)里的共享充電寶為例,這個(gè)簡(jiǎn)單來(lái)說(shuō)就是一個(gè)池化的思維。

每個(gè)充電寶只有一個(gè)屬性,那就是剩余電量。用于模擬,只有一個(gè)方法,就是借出去被使用。

那么我們需要自己實(shí)現(xiàn)的 PooledObjectFactory 可以是:

- 第一個(gè) makeObject 方法 :用于對(duì)象的新建,一般是 new 出來(lái)之后包裝一下。而什么時(shí)候需要新建呢,根據(jù)策略不同則時(shí)機(jī)不同。例如在沒(méi)有閑置資源對(duì)象,且已存在的資源數(shù)不超過(guò)所設(shè)置的最大資源時(shí)新建。
- 第二個(gè) destroyObject 方法:銷毀一個(gè)對(duì)象,除了很容易想到的閑置過(guò)長(zhǎng)時(shí)間被清理掉了導(dǎo)致需要銷毀之外,還有如果進(jìn)行了第三個(gè)方法且返回了 false ,那么也是需要銷毀的。
- 第三個(gè) validateObject方法:檢驗(yàn)這個(gè)對(duì)象是否還有有效,借出和歸還時(shí),以及內(nèi)置后臺(tái)線程檢測(cè)閑置情況時(shí),可以通過(guò)驗(yàn)證可以去除一些不符合業(yè)務(wù)邏輯的資源對(duì)象。默認(rèn)這個(gè)方法是不被調(diào)用的,要開(kāi)啟則需要在PoolConfig中設(shè)置setTestOnBorrow , setTestOnReturn , setTestWhileIdle等屬性。
第一個(gè) activeObject 方法: 在借用一個(gè)對(duì)象的時(shí)候調(diào)用,則可以在此重置其內(nèi)部狀態(tài),那么返回的對(duì)象就像新的一樣,例如這里重置電量
第一個(gè) passivateObject 方法: 對(duì)應(yīng) activateObject 方法,是在歸還一個(gè)對(duì)象的時(shí)候調(diào)用,注意不應(yīng)與activateObject方法有業(yè)務(wù)邏輯上的沖突
用于測(cè)試的主函數(shù):

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot Java后端實(shí)現(xiàn)okhttp3超時(shí)設(shè)置的方法實(shí)例
Okhttp的使用沒(méi)有httpClient廣泛,網(wǎng)上關(guān)于Okhttp設(shè)置代理的方法很少,下面這篇文章主要給大家介紹了關(guān)于SpringBoot Java后端實(shí)現(xiàn)okhttp3超時(shí)設(shè)置的相關(guān)資料,需要的朋友可以參考下2021-10-10
java實(shí)現(xiàn)調(diào)用http請(qǐng)求的五種常見(jiàn)方式
在實(shí)際開(kāi)發(fā)過(guò)程中,我們經(jīng)常需要調(diào)用對(duì)方提供的接口或測(cè)試自己寫(xiě)的接口是否合適,本文主要介紹了java實(shí)現(xiàn)調(diào)用http請(qǐng)求的四種常見(jiàn)方式,感興趣的可以了解一下2024-07-07
MVC+DAO設(shè)計(jì)模式下的設(shè)計(jì)流程詳解
這篇文章主要介紹了MVC+DAO設(shè)計(jì)模式下的設(shè)計(jì)流程詳解,分別介紹了數(shù)據(jù)庫(kù)設(shè)計(jì)、設(shè)計(jì)符合java bean標(biāo)準(zhǔn)的entity類、設(shè)計(jì)訪問(wèn)數(shù)據(jù)庫(kù)的DAO接口等內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
JavaMail整合Spring實(shí)現(xiàn)郵件發(fā)送功能
這篇文章主要為大家詳細(xì)介紹了JavaMail整合Spring實(shí)現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
打開(kāi).properties中文顯示unicode編碼問(wèn)題以及解決
這篇文章主要介紹了打開(kāi).properties中文顯示unicode編碼問(wèn)題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
java實(shí)現(xiàn)一個(gè)簡(jiǎn)單TCPSocket聊天室功能分享
這篇文章主要為大家分享了java實(shí)現(xiàn)的一個(gè)簡(jiǎn)單TCPSocket聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-04-04
MyBatisPlus+SpringBoot實(shí)現(xiàn)樂(lè)觀鎖功能詳細(xì)流程
樂(lè)觀鎖是針對(duì)一些特定問(wèn)題的解決方案,主要解決丟失更新問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于MyBatisPlus+SpringBoot實(shí)現(xiàn)樂(lè)觀鎖功能的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
MybatisPlus使用queryWrapper如何實(shí)現(xiàn)復(fù)雜查詢
這篇文章主要介紹了MybatisPlus使用queryWrapper如何實(shí)現(xiàn)復(fù)雜查詢,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。2022-01-01
Java使用WebView實(shí)現(xiàn)桌面程序的技術(shù)指南
在現(xiàn)代軟件開(kāi)發(fā)中,許多應(yīng)用需要在桌面程序中嵌入 Web 頁(yè)面,例如,你可能需要在 Java 桌面應(yīng)用中嵌入一部分 Web 前端,或者加載一個(gè) HTML5 界面以增強(qiáng)用戶體驗(yàn),所以本文給大家介紹了Java使用WebView實(shí)現(xiàn)桌面程序的技術(shù)指南,需要的朋友可以參考下2025-05-05

