1 一些廢話
作為一名Java開發(fā)人員,池化技術(shù)或多或少在業(yè)務(wù)代碼中使用。常見的包括線程池、連接池等。也是因?yàn)镴ava語言超級豐富的基建,基本上這些池化能力都有著相對成熟的“工具”。
比如,需要使用線程池的時(shí)候常常會選擇Spring提供的 ThreadPoolTaskExecutor , 工具內(nèi)部替我們維護(hù)了線程的生命周期與任務(wù)的狀態(tài)變化。
線程池的運(yùn)轉(zhuǎn)流程圖
2 正文開始
在筆者的業(yè)務(wù)場景里,java服務(wù)需要通過命令行啟動一個(gè)特殊進(jìn)程,并在進(jìn)程使用完后將其銷毀。而業(yè)務(wù)對啟動這個(gè)進(jìn)程的整體耗時(shí)較為敏感,打算利用池化技術(shù),將進(jìn)程池化復(fù)用,去除啟動進(jìn)程的消耗,達(dá)到優(yōu)化性能的目標(biāo)。
認(rèn)識 GenericObjectPool
池化技術(shù)的概念大家可能都比較熟悉了,但真正要從零開始實(shí)現(xiàn)池化能力,就會感覺困難很多。好在Java豐富的基建在提供ThreadPoolTaskExecutor的同時(shí),也提供了GenericObjectPool這個(gè)輔助我們實(shí)現(xiàn)自定義對象池化的工具。順帶提一句:JedisPool就是使用這個(gè)工具實(shí)現(xiàn)的。
GenericObjectPool構(gòu)造方法一共就3個(gè)參數(shù),只有PooledObjectFactory必傳;
/** *Createsanew{@codeGenericObjectPool}thattracksanddestroys *objectsthatarecheckedout,butneverreturnedtothepool. * *@paramfactoryTheobjectfactorytobeusedtocreateobjectinstances *usedbythispool *@paramconfigThebasepoolconfigurationtouseforthispoolinstance. *Theconfigurationisusedbyvalue.Subsequentchangesto *theconfigurationobjectwillnotbereflectedinthe *pool. *@paramabandonedConfigConfigurationforabandonedobjectidentification *andremoval.Theconfigurationisusedbyvalue. */ publicGenericObjectPool(finalPooledObjectFactoryfactory, finalGenericObjectPoolConfig config,finalAbandonedConfigabandonedConfig){ }
PooledObjectFactory 按照方法注釋的描述,它是專門負(fù)責(zé)給池子創(chuàng)建對象實(shí)例的。當(dāng)然除了創(chuàng)建對象(makeObject), 還包括了檢驗(yàn)、激活、銷毀對象。基本涵蓋了對象生命周期中的各個(gè)階段。
voidactivateObject(PooledObjectp)throwsException; voiddestroyObject(PooledObject p)throwsException; PooledObject makeObject()throwsException; voidpassivateObject(PooledObject p)throwsException; booleanvalidateObject(PooledObject p);
更加詳細(xì)的說明可以瀏覽 GenericObjectPool's apidocs [1]。源碼的注釋也很詳細(xì)值得一看。
使用 GenericObjectPool
先引入依賴
org.apache.commons commons-pool2 ${version}
根據(jù)自身業(yè)務(wù)實(shí)現(xiàn)PooledObjectFactory接口;作者的業(yè)務(wù)場景是進(jìn)程池化,那么對應(yīng)的創(chuàng)建對象、銷毀對象的方法就是創(chuàng)建進(jìn)程和銷毀進(jìn)程的代碼。
publicclassMyProcessFactoryimplementsPooledObjectFactory{ @Override publicvoiddestroyObject(PooledObject p)throwsException{ finalMyProcessprocess=p.getObject(); if(null!=process){ //銷毀進(jìn)程 process.stop(); } } @Override publicPooledObject makeObject()throwsException{ //這里就是去創(chuàng)建一個(gè)進(jìn)程 MyProcessprocess=newMyProcess(); process.start(); returnnewDefaultPooledObject<>(process); } //剩下幾個(gè)方法也可以按需實(shí)現(xiàn) }
下一步就是構(gòu)建 GenericObjectPool 實(shí)例
PooledObjectFactoryfactory=newMyProcessFactory(); GenericObjectPool pool=newGenericObjectPool(factory);
使用GenericObjectPool
//獲取進(jìn)程實(shí)例 MyProcessprocess=pool.borrowObject(); //歸還實(shí)例 pool.returnObject(process);
進(jìn)階使用 GenericObjectPoolConfig
顧名思義,GenericObjectPoolConfig是池化工具的配置類;它包含了池的最大容量、池的最大空閑數(shù)、最小空閑數(shù)等核心參數(shù)。除此之外在它的父類 BaseObjectPoolConfig 中,空閑對象檢測規(guī)則,對象存放隊(duì)列進(jìn)出規(guī)則(LIFO)等更加細(xì)節(jié)的配置。
/** *Thedefaultvalueforthe{@codemaxTotal}configurationattribute. *@seeGenericObjectPool#getMaxTotal() */ publicstaticfinalintDEFAULT_MAX_TOTAL=8; /** *Thedefaultvalueforthe{@codemaxIdle}configurationattribute. *@seeGenericObjectPool#getMaxIdle() */ publicstaticfinalintDEFAULT_MAX_IDLE=8; /** *Thedefaultvalueforthe{@codeminIdle}configurationattribute. *@seeGenericObjectPool#getMinIdle() */ publicstaticfinalintDEFAULT_MIN_IDLE=0;
通過調(diào)整這些參數(shù)值,就能創(chuàng)建符合業(yè)務(wù)要求的池子。下面就是能常駐4個(gè)進(jìn)程的一套配置參數(shù)。
privateGenericObjectPoolConfiggenericObjectPoolConfig(){ finalGenericObjectPoolConfig config=newGenericObjectPoolConfig<>(); config.setMaxTotal(20);//池的最大容量 config.setMaxIdle(4);//最大空閑連接數(shù) config.setMinIdle(0);//最小空閑連接數(shù) config.setMaxWait(Duration.ofSeconds(5));//獲取對象時(shí)最大等待時(shí)間 config.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));//空閑對象檢查間隔 config.setMinEvictableIdleTime(Duration.ofMinutes(10));//空閑對象被移除的最小空閑時(shí)間 config.setTestOnBorrow(true); config.setLifo(false); returnconfig; }
3 后續(xù)
當(dāng)然真實(shí)的業(yè)務(wù)中還會有很多不相關(guān)的邏輯夾雜其中,上文基本涵蓋了池化對象搭建與配置的實(shí)現(xiàn)方法。最終也實(shí)現(xiàn)了性能優(yōu)化的目標(biāo)。希望此文能為大家在池化運(yùn)用多些幫助。
-
JAVA
+關(guān)注
關(guān)注
20文章
2986瀏覽量
107073 -
線程池
+關(guān)注
關(guān)注
0文章
57瀏覽量
7095 -
命令行
+關(guān)注
關(guān)注
0文章
80瀏覽量
10537 -
池化
+關(guān)注
關(guān)注
0文章
4瀏覽量
1170
發(fā)布評論請先 登錄
動態(tài)線程池思想學(xué)習(xí)及實(shí)踐

買藥秒送 JADE動態(tài)線程池實(shí)踐及原理淺析

OpenHarmony3.1 Release版本特性解析——OpenHarmony硬件資源池化架構(gòu)介紹
分布式系統(tǒng)硬件資源池原理和接入實(shí)踐
基于CXL技術(shù)的大內(nèi)存池化方案解析
基于Nacos的簡單動態(tài)化線程池實(shí)現(xiàn)
公用池化包Commons Pool 2

卷積神經(jīng)網(wǎng)絡(luò)中的池化方式

高并發(fā)內(nèi)存池項(xiàng)目實(shí)現(xiàn)

了解連接池、線程池、內(nèi)存池、異步請求池

內(nèi)存池主要解決的問題

線程池的運(yùn)轉(zhuǎn)流程圖 池化技術(shù)實(shí)踐案例解析

評論