對象池技術(shù)概述_第1頁
對象池技術(shù)概述_第2頁
對象池技術(shù)概述_第3頁
對象池技術(shù)概述_第4頁
對象池技術(shù)概述_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

commons-poolAPI,將用完的對象返回對象池中說,能夠提高應(yīng)用的性能。commons-dbcpcommons-poolcommons-dbcpcommons-pooltomcatJNDIjavax.sql.DataSource使用dbcporg.apachemons.dbcp.BasicDataSource。我們可以從這個稱為“數(shù)據(jù)源”的類中調(diào)用getConnection方法來獲得與數(shù)據(jù)外部使用者來說是透亮的。BasicDataSourcegetConnectionPoolingDataSourcegetConnectionPoolingDataSourceObjectPool,在getConnectionObjectPoolObjectPool.borrowObjectcommons-poolObjectPoolFactorydbcporg.apachemons.pool.PoolableObjectFactoryorg.apachemons.dbcp.PoolableConnectionFactorymakeObjectConnectionPoolableConnectionFactoryConnectionFactory,ConnectionFactory3ConnectionDriverConnectionFactoryDriverConnection。最近在做一個內(nèi)部測試工具類的優(yōu)化工作中接觸到了連接池,對象池技術(shù),將原事實證明,經(jīng)過兩次改造,原來一個比較大的測試類需要500多秒,第一次優(yōu)化后只需要30080改造過程中的一些總結(jié).么請使用對象池.內(nèi)部原理簡潔的說,就是將創(chuàng)立的對象放到一個容器中,用完之后不是銷毀而是再放回該容器,讓其他的對象調(diào)用,對象池中還涉及到一池中沒有可用空閑對象時等待等等.之前,這里先理解幾個概念:并且包含了用來創(chuàng)立池對象的工廠對象池對象:就是要放到池容器中的對象,理論上可以是任何對象.說的.池對象工廠(PoolableObjectFactory接口):用來創(chuàng)立池對象,將不用的池對象進(jìn)展鈍化(passivateObject),(activeObject),池對象進(jìn)展驗證(validateObject),對有問題的池對象進(jìn)展銷毀(destroyObject)等工作對象池中封裝了創(chuàng)立,獵取,歸還,銷毀池對象的職責(zé),固然這些工作都是通會對容器大小,存放時間,訪問等待時間,空閑時間等等進(jìn)展一些掌握,由于可以依據(jù)需要來調(diào)整這些設(shè)置.到達(dá)池容器的最大值,而對象池中又經(jīng)沒有空閑的對象,那么將會連續(xù)等待,個限度,對象池就會拋出特別.BasePoolableObjectFactory.addObject以備后用.為了確保對對象池的訪問都是線程安全的,全部對容器的操作都必需放在synchronizedapachecommon-pool5:GenericObjectPoolGenericKeyedObjectPool,SoftReferenceObjectPool,StackObjectPool,StackKeyedObjectPool.五種對象池可分為兩類,一類是無keykeyCursorableLinkedList來做容器,SoftReferenceObjectPoolArrayList用(SoftReferencejvm圾回收,從而具有很強(qiáng)的緩存力量.最終兩種用Stackkey池是對前面池技術(shù)原理的一種簡潔實現(xiàn),帶key的相對簡單一些,它會將池對keykeykey,keymakeObject方法創(chuàng)立的對象根本上都是一模一樣的,由于沒法傳遞參數(shù)來對池對象進(jìn)展定制.因此四種池對象的區(qū)分主要表達(dá)在內(nèi)部的容器的區(qū)分,CursorableLinkedList內(nèi)部用游標(biāo)(cursor)來定位當(dāng)前元素的雙向鏈表,是非線程安全的,但是能滿足對容器的并發(fā)修改.ArrayListreturnObject,銷毀clear,close.下面是一些時序圖:borrowObject:returnObject:invalidateObject:apachecommon-dbcpcommon-poolcommon-dbcpConnection,StatmentPoolableConnection,PoolablePreparedStatement.JavaJavaJavaJava_pool.returnObject(_key,this);這樣一句,將連接對象放回連接池中.ObjectPool,KeyedObjectPool,由于一個數(shù)據(jù)庫只對應(yīng)一個連接,而執(zhí)行操作的StatementSqlsql在對連接池的治理上,common-dbcp主要承受兩種對象:PoolingDriver,另一個是PoolingDataSource,二者的區(qū)分是PoolingDriver連接池,即一個數(shù)據(jù)源對應(yīng)一個連接池.下面是common-dbcp的構(gòu)造關(guān)系:Java下面是參考了common-dbcpJava1./***創(chuàng)立連接3. *4. *@since2023-1-2202:58:355. */publicclassConnectionUtils{//common-dbcpprotocol privatestaticfinalStringPOOL_DRIVER_KEY=“jdbc:apache:commons:dbcp:“; privatestaticfinalStringPOLLING_DRIVER=“mons.dbcp.PoolingDriver“;10.11. /**12. *取得池化驅(qū)動器13. **@return*@throwsClassNotFoundException*@throwsSQLException17. */privatestaticPoolingDrivergetPoolDriverthrowsClassNotFoundException,SQLException{Class.forName(POLLING_DRIVER);return(PoolingDriver)DriverManager.getDriver(POOL_DRIVER_KEY);22. }23.24. /**25. *銷毀全部連接26. *27. *@throwsException28. */publicstaticvoiddestorythrowsException{PoolingDriverdriver=getPoolDriver;String[]names=driver.getPoolNames;for(Stringname:names){driver.getConnectionPool(name).close;34. }35. }36.37. /**38. *從連接池中獵取數(shù)據(jù)庫連接39. */publicstaticConnectiongetConnection(TableMetaDatatable)throwsException{Stringkey=table.getConnectionKey;43.44. PoolingDriverdriver=getPoolDriver;45.ObjectPoolpool=null;//catchtry{pool=driver.getConnectionPool(key);}catch(Exceptione){51. }52.if(pool==null){//依據(jù)數(shù)據(jù)庫類型構(gòu)建連接工廠ConnectionFactoryconnectionFactory=null;if(table.getDbAddr!=null&&TableMetaData.DB_TYPE_MYSQL==table.getDbType){Class.forName(TableMetaData.MYSQL_DRIVER);connectionFactory=newDriverManagerConnectionFactory(table.getDBUrl,null);}else{Class.forName(TableMetaData.ORACLE_DRIVER);connectionFactory=newDriverManagerConnectionFactory(table.getDBUrl,table.getDbuser,table.getDbpass);65. }66.//構(gòu)造連接池ObjectPoolconnectionPool=newGenericObjectPool(null);newPoolableConnectionFactory(connectionFactory,connectionPool,70.null,null,false,true);71.72.//driver73.driver.registerPool(key,connectionPool);74.}75.//從連接池中拿一個連接returnDriverManager.getConnection(POOL_DRIVER_KEY+key);78. }79.80.}Java對象的生命周期大致包括三個階段:對象的創(chuàng)立,對象的使用,對象的去除。因此,對象的生命周期長度可Java對象的生命周期大致包括三個階段:對象的創(chuàng)立,對象的使用,對象的去除。因此,對象的生命周期長度可用如下的表達(dá)式表示:T=T1+T2+T3。其中T1T2T3其去除時間。由此,我們可以看出,只有T2是真正有效的時間,而T1、T3則是對象本身的開銷。下面再看看T1、T3我們知道,Java對象是通過構(gòu)造函數(shù)來創(chuàng)立的,在這一過程中,該構(gòu)造函數(shù)鏈中的全部構(gòu)造函數(shù)也都會被自Javal整數(shù)變量(byte、short、int、long0,float和double0.0,規(guī)律值設(shè)置成false。所以用new11一些操作所消耗時間的比照表運(yùn)算操作例如標(biāo)準(zhǔn)化時間本地賦值i=n1.0實例賦值this.i=n1.2方法調(diào)用Funct5.9建對象NewObject980建數(shù)組Newint[10]31001980980166倍,而假設(shè)建一個數(shù)組所花費(fèi)的時間就更多了。再看去除對象的過程。我們知道,Java語言的一個優(yōu)勢,就是Java程序員勿需再像C/C++程序員那樣,顯式地釋放對象,而由稱為垃圾收集器(GarbageCollector)的自動內(nèi)存治理系統(tǒng),定時或在內(nèi)存凸現(xiàn)出缺乏時,自動回收垃圾對象所占的內(nèi)存。凡事有利總也有弊,這雖然為Java程序設(shè)計者供給了極大的便利,但同時它也帶來了較大的性能開銷。這種開銷包括兩方面,首先是對象治理開銷,GC為了能夠正確釋放對象,它必需監(jiān)控每一個對象的運(yùn)行狀態(tài),包括對象的申請、引用、被引用、賦值等。其次,在GC開頭回收“垃圾”對象時,系統(tǒng)會暫停應(yīng)用程序的執(zhí)行,而單獨(dú)占用CPU。T1、T3的時間,而這些均可以通過對象池技術(shù)來實現(xiàn)。對象池技術(shù)的根本原理對象池技術(shù)根本原理的核心有兩點(diǎn):緩存和共享,即對于那些被頻繁使用的對象,在使用完后,不馬上將它們釋放,而是將它們緩存起來,以供后續(xù)的應(yīng)用程序重復(fù)使用,從而削減創(chuàng)立對象和釋放對象的次數(shù),進(jìn)而改善實現(xiàn)一個對象池,一般會涉及到如下的類:對象池工廠(ObjectPoolFactory)類該類主要用于治理一樣類型和設(shè)置的對象池(ObjectPool),它一般包含如下兩個方法:·createPool:用于創(chuàng)立特定類型和設(shè)置的對象池;·destroyPool:用于釋放指定的對象池;同時為保證ObjectPoolFactory的單一實例,可以承受Singleton設(shè)計模式,見下述getInstance方法的實現(xiàn):publicstaticpublicstaticObjectPoolFactorygetInstance{if(poolFactory==null){poolFactory=newObjectPoolFactory;}returnpoolFactory;}2)參數(shù)對象(ParameterObject)類2)參數(shù)對象(ParameterObject)類該類主要用于封裝所創(chuàng)立對象池的一些屬性參數(shù),如池中可存放對象的數(shù)目的最大值(maxCount)、最小值(minCount)等。3)對象池(ObjectPool)類用于治理要被池化對象的借出和歸還,并通知PoolableObjectFactory完成相應(yīng)的工作。它一般包含如下兩個方法:·getObject:用于從池中借出對象;·returnObject:將池化對象返回到池中,并通知全部處于等待狀態(tài)的線程;4)池化對象工廠(PoolableObjectFactory)類該類主要負(fù)責(zé)治理池化對象的生命周期,就簡潔來說,一般包括對象的創(chuàng)立及銷毀。該類同通用對象池的實現(xiàn)對象池的構(gòu)造和治理可以依據(jù)多種方式實現(xiàn)。最敏捷的方式是將池化對象的Class類型在對象池之外指定,即在ObjectPoolFactory類創(chuàng)立對象池時,動態(tài)指定該對象池所池化對象的Class類型,其實現(xiàn)代碼如下:...public...publicObjectPoolcreatePool(ParameterObjectparaObj,ClassclsType){returnnewObjectPool(paraObj,clsType);}...其中,paraObj參數(shù)用于指定對象池的特征屬性,clsType參數(shù)則指定了該對象池所存放對象的類型。對象池(ObjectPool)創(chuàng)立以后,下面就是利用它來治理對象了,具體實現(xiàn)如下:publicclassObjectPool{privateParameterObjectparaObj;//該對象池的屬性參數(shù)對象privateClassclsType;//該對象池中所存放對象的類型privateintcurrentNum=0;//該對象池當(dāng)前已創(chuàng)立的對象數(shù)目privateObjectcurrentObj;//該對象池當(dāng)前可以借出的對象privateVectorpool;//用于存放對象的池publicObjectPool(ParameterObjectparaObj,ClassclsType){this.paraObj=paraObj;this.clsType=clsType;pool=newVector;}publicObjectgetObject{if(pool.size<=paraObj.getMinCount){if(currentNum<=paraObj.getMaxCount){//假設(shè)當(dāng)前池中無對象可用,而且已創(chuàng)立的對象數(shù)目小于所限制的最大值,就利用//PoolObjectFactoryPoolableObjectFactoryobjFactory=PoolableObjectFactory.getInstance;currentObj=objFactory.createObject(clsType);currentNum++;}else{//假設(shè)當(dāng)前池中無對象可用,而且所創(chuàng)立的對象數(shù)目已到達(dá)所限制的最大值,//就只能等待其它線程返回對象到池中synchronized(this){try{wait;}catch(InterruptedExceptione){System.out.println(e.getMessage);e.printStackTrace;}currentObj=pool.firstElement;}}}else{//假設(shè)當(dāng)前池中有可用的對象,就直接從池中取出對象currentObj=pool.firstElement;}returncurrentObj;}publicvoidreturnObject(Objectobj){//確保對象具有正確的類型if(obj.isInstance(clsType)){pool.addElement(obj);synchronized(this){notifyAll;}}else{thrownewthrownewIllegalArgumentException(“該對象池不能存放指定的對象類型“);}}}從上述代碼可以看出,ObjectPool從上述代碼可以看出,ObjectPool利用一個java.util.Vector指定池化對象的Class類型及對象池的一些屬性。在有對象返回到對象池時,它將檢查對象的類型是否正確。當(dāng)對象實例的創(chuàng)立并不在ObjectPool類中,而是由PoolableObjectFactory類的createObject具體實現(xiàn)如下:...publicObjectcreateObject(ClassclsType){Objectobj=null;try{obj=clsType.newInstance;}catch(Exceptione){e.printStackTrace;}returnobj;}...(Client)如何來使ClassStringBuffer:...//創(chuàng)立對象池工廠ObjectPoolFactorypoolFactory=ObjectPoolFactory.getInstance;//定義所創(chuàng)立對象池的屬性ParameterObjectparaObj=newParameterObject(2,1);//StringBufferObjectPoolpool=poolFactory.createPool(paraObj,StringBuffer.class);//StringBufferStringBufferbuffer=(StringBuffer)pool.getObject;//StringBufferbuffer.append(“hello“);System.out.println(buffer.toString);......但圓滿的是,由于需要使用大量的類型定型(cast)操作,再加上一些對Vector類的同步操作,使得它在某些狀況下對性能的改進(jìn)格外有限,尤其對那些創(chuàng)立周期比較短的對象。專用對象池的實現(xiàn)由于通用對象池的治理開銷比較大,某種程度上抵消了重用對象所帶來的大局部優(yōu)勢。為解決該問題,可以承受專用對象池的方法。即對象池所池化對象的Class類型不是動態(tài)指定的,而是預(yù)先就已指定。這樣,它在實ObjectPoolFactory和PoolableObjectFactory接融合到ObjectPoolClass類型仍為StringBuffer,而用省略號表示的地方,表示代碼同通用對象池的實現(xiàn)):publ

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論