欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java中對(duì)象池的介紹與使用

 更新時(shí)間:2023年02月21日 15:28:06   作者:Dream_bin  
對(duì)象池,顧名思義就是一定數(shù)量的已經(jīng)創(chuàng)建好的對(duì)象(Object)的集合。這篇文章主要為大家介紹了Java中對(duì)象池的介紹與使用,感興趣的可以了解一下

1. 什么是對(duì)象池

對(duì)象池,顧名思義就是一定數(shù)量的已經(jīng)創(chuàng)建好的對(duì)象(Object)的集合。當(dāng)需要?jiǎng)?chuàng)建對(duì)象時(shí),先在池子中獲取,如果池子中沒(méi)有符合條件的對(duì)象,再進(jìn)行創(chuàng)建新對(duì)象,同樣,當(dāng)對(duì)象需要銷毀時(shí),不做真正的銷毀,而是將其setActive(false),并存入池子中。這樣就避免了大量對(duì)象的創(chuàng)建。

2. 對(duì)象池解決什么問(wèn)題

減少頻繁創(chuàng)建和銷毀對(duì)象帶來(lái)的成本,實(shí)現(xiàn)對(duì)象的緩存和復(fù)用,創(chuàng)建對(duì)象的成本比較大,并且創(chuàng)建比較頻繁。比如線程的創(chuàng)建代價(jià)比較大,于是就有了常用的線程 池。對(duì)象池(模式)是一種創(chuàng)建型設(shè)計(jì)模式,它持有一個(gè)初始化好的對(duì)象的集合,將對(duì)象提供給調(diào)用者。

一般而言對(duì)于 創(chuàng)建對(duì)象的成本比較大,并且創(chuàng)建比較頻繁。比如線程的創(chuàng)建代價(jià)比較大,于是就有了常用的線程池。

3. 對(duì)象池的優(yōu)缺點(diǎn)

3.1 對(duì)象池的優(yōu)點(diǎn)

提升了t獲取對(duì)象的響應(yīng)速度,比如單個(gè)線程和資源連接的創(chuàng)建成本都比較大。

運(yùn)用對(duì)象池化技術(shù)可以顯著地提升性能,尤其是當(dāng)對(duì)象的初始化過(guò)程代價(jià)較大或者頻率較高時(shí)。

一定程度上減少了GC的壓力。對(duì)于實(shí)時(shí)性要求較高的程序有很大的幫助

比如說(shuō) http 鏈接的對(duì)象池,Redis對(duì)象池等等都使用了對(duì)象池

3.2 對(duì)象池弊端

1.臟對(duì)象的問(wèn)題

所謂的臟對(duì)象就是指的是當(dāng)對(duì)象被放回對(duì)象池后,還保留著剛剛被客戶端調(diào)用時(shí)生成的數(shù)據(jù)。

臟對(duì)象可能帶來(lái)兩個(gè)問(wèn)題:

1).臟對(duì)象持有上次使用的引用,導(dǎo)致內(nèi)存泄漏等問(wèn)題。

2). 臟對(duì)象如果下一次使用時(shí)沒(méi)有做清理,可能影響程序的處理數(shù)據(jù)。

2.生命周期的問(wèn)題

處于對(duì)象池中的對(duì)象生命周期要比普通的對(duì)象要長(zhǎng)久。維持大量的對(duì)象也是比較占用內(nèi)存空間的。

4. 對(duì)象池有什么特征

一般來(lái)說(shuō),對(duì)象池有下面幾個(gè)特征:

(1)對(duì)象池中有一定數(shù)量已經(jīng)創(chuàng)建好的對(duì)象

(2)對(duì)象池向用戶提供獲取對(duì)象的接口,當(dāng)用戶需要新的對(duì)象時(shí),便可通過(guò)調(diào)用此接口獲取新的對(duì)象。如果對(duì)象池中有事先創(chuàng)建好的對(duì)象時(shí),就直接返回給用 戶;如果沒(méi)有了,對(duì)象池還可以創(chuàng)建新的對(duì)象加入其中,然后返回給用戶

(3)對(duì)象池向用戶提供歸還對(duì)象的接口,當(dāng)用戶不再使用某對(duì)象時(shí),便可通過(guò)此接口把該對(duì)象歸還給對(duì)象池

5. 池的大小選擇

通常情況下,我們需要控制對(duì)象池的大小如果對(duì)象池沒(méi)有限制,可能導(dǎo)致對(duì)象池持有過(guò)多的閑置對(duì)象,增加內(nèi)存的占用。如果對(duì)象池閑置過(guò)小,沒(méi)有可用的對(duì)象時(shí),會(huì)造成之前對(duì)象池?zé)o可用的對(duì)象時(shí),再次請(qǐng)求出現(xiàn)的問(wèn)題。

對(duì)象池的大小選取應(yīng)該結(jié)合具體的使用場(chǎng)景,結(jié)合數(shù)據(jù)(觸發(fā)池中無(wú)可用對(duì)象的頻率)分析來(lái)確定?,F(xiàn)在Java的對(duì)象分配操作不比c語(yǔ)言的malloc調(diào)用慢, 對(duì)于輕中量級(jí)的對(duì)象, 分配/釋放對(duì)象的開銷可以忽略不計(jì),并發(fā)環(huán)境中, 多個(gè)線程可能(同時(shí))需要獲取池中對(duì)象, 進(jìn)而需要在堆數(shù)據(jù)結(jié)構(gòu)上進(jìn)行同步或者因?yàn)殒i競(jìng)爭(zhēng)而產(chǎn)生阻塞, 這種開銷要比創(chuàng)建銷毀對(duì)象的開銷高數(shù)百倍;由于池中對(duì)象的數(shù)量有限, 勢(shì)必成為一個(gè)可伸縮性瓶頸;很難正確的設(shè)定對(duì)象池的大小, 如果太小則起不到作用, 如果過(guò)大, 則占用內(nèi)存資源高。

空間換時(shí)間的折中,本質(zhì)上,對(duì)象池屬于空間換時(shí)間的折中。它通過(guò)緩存初始化好的對(duì)象來(lái)提升調(diào)用者請(qǐng)求對(duì)象的響應(yīng)速度。除此之外,折中(tradeoff)是軟件開發(fā)中的一個(gè)重要的概念,會(huì)貫穿整個(gè)軟件開發(fā)過(guò)程中。

6. 對(duì)象池的使用

6.1 接入

 <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>

6.2 實(shí)現(xiàn)線程池工廠

import com.scl.online.service.model.SxInferContext;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;

 /**
 * 實(shí)現(xiàn)PooledObjectFactory 
 * 
 * @author : cuilinsu
 * @since : 2021/4/14 17:56
 */
public class InferContextPooledObjectFactory implements PooledObjectFactory<SxInferContext> {

  @Override
  public PooledObject<SxInferContext> makeObject() {
    SxInferContext inferContext = new SxInferContext();
    return new DefaultPooledObject<>(inferContext);
  }

  @Override
  public void destroyObject(PooledObject<SxInferContext> pooledObject) {

  }

  @Override
  public boolean validateObject(PooledObject<SxInferContext> pooledObject) {
    return true;
  }

  @Override
  public void activateObject(PooledObject<SxInferContext> pooledObject) {
    pooledObject.getObject().initObject();
  }

  @Override
  public void passivateObject(PooledObject<SxInferContext> pooledObject) {
    // 當(dāng)ObjectPool實(shí)例返還池中的時(shí)候調(diào)用
    pooledObject.getObject().initObject();
  }
}

說(shuō)明:

1.SxInferContext:為對(duì)象池里頭的對(duì)象,對(duì)象借還都會(huì)調(diào)用到PooledObjectFactory里頭的方法

2.PooledObjectFactory負(fù)責(zé)管理PooledObject,如:借出對(duì)象,返回對(duì)象,校驗(yàn)對(duì)象,有多少激活對(duì)象,有多少空閑對(duì)象。

方法描述
makeObject用于生成一個(gè)新的ObjectPool實(shí)例
activateObject每一個(gè)鈍化(passivated)的ObjectPool實(shí)例從池中借出(borrowed)前調(diào)用
validateObject可能用于從池中借出對(duì)象時(shí),對(duì)處于激活(activated)狀態(tài)的ObjectPool實(shí)例進(jìn)行測(cè)試確保它是有效的。也有可能在ObjectPool實(shí)例返還池中進(jìn)行鈍化前調(diào)用進(jìn)行測(cè)試是否有效。它只對(duì)處于激活狀態(tài)的實(shí)例調(diào)用
passivateObject當(dāng)ObjectPool實(shí)例返還池中的時(shí)候調(diào)用
destroyObject當(dāng)ObjectPool實(shí)例從池中被清理出去丟棄的時(shí)候調(diào)用(是否根據(jù)validateObject的測(cè)試結(jié)果由具體的實(shí)現(xiàn)在而定)

6.3 初始化

public GenericObjectPool<SxInferContext> contextPools;

@PostConstruct
  public void init() {
    if (sxInferConfig.isObjectPoolUsable()) {
      InferContextPooledObjectFactory factory = new InferContextPooledObjectFactory();
      //設(shè)置對(duì)象池的相關(guān)參數(shù)
      GenericObjectPoolConfig poolConfig = initConfig();
      //新建一個(gè)對(duì)象池,傳入對(duì)象工廠和配置
      contextPools = new GenericObjectPool<>(factory, poolConfig);
    }
  }


   /**
   \* 池子初始化
   *
   \* @param
   */
  public GenericObjectPoolConfig initConfig() {
    GenericObjectPoolConfig cfg = new GenericObjectPoolConfig();
    cfg.setJmxNamePrefix("objectPool");
    //  對(duì)象總數(shù)
    cfg.setMaxTotal(sxInferConfig.getPoolMaxTotal());
    // 最大空閑對(duì)象數(shù)
    cfg.setMaxIdle(sxInferConfig.getPoolMaxIdle());
    // 最小空閑對(duì)象數(shù)
    cfg.setMinIdle(sxInferConfig.getPoolMinIdle());
    // 借對(duì)象阻塞最大等待時(shí)間
    // 獲取資源的等待時(shí)間。blockWhenExhausted 為 true 時(shí)有效。-1 代表無(wú)時(shí)間限制,一直阻塞直到有可用的資源
    cfg.setMaxWaitMillis(sxInferConfig.getPoolMaxWait());
    // 最小驅(qū)逐空閑時(shí)間
    cfg.setMinEvictableIdleTimeMillis(sxInferConfig.getPoolMinEvictableIdleTimeMillis());
    // 每次驅(qū)逐數(shù)量  資源回收線程執(zhí)行一次回收操作,回收資源的數(shù)量。默認(rèn) 3
    cfg.setNumTestsPerEvictionRun(sxInferConfig.getPoolNumTestsPerEvictionRun());
    // 回收資源線程的執(zhí)行周期,默認(rèn) -1 表示不啟用回收資源線程
    cfg.setTimeBetweenEvictionRunsMillis(sxInferConfig.getPoolTimeBetweenEvictionRunsMillis());
    // 資源耗盡時(shí),是否阻塞等待獲取資源,默認(rèn) true
    cfg.setBlockWhenExhausted(sxInferConfig.isPoolBlockWhenExhausted());
    return cfg;
  }

6.4 使用

contextPools.borrowObject();
contextPools.returnObject();
等等 ....

說(shuō)明:cfg.setJmxNamePrefix(“objectPool”); 假如項(xiàng)目中有用到redis線程池,則需要配置一下JmxNamePrefix。redis線程池使用的是“pool”,假如有重復(fù)的,早調(diào)用線程池是時(shí),就默認(rèn)會(huì)調(diào)用到Redis線程池的PooledObjectFactory(假如redis線程池使用默認(rèn)的話),導(dǎo)致配置的線程池不生效。

GenericObjectPool 方法解釋:

方法描述
borrowObject從池中借出一個(gè)對(duì)象。要么調(diào)用PooledObjectFactory.makeObject方法創(chuàng)建,要么對(duì)一個(gè)空閑對(duì)象使用PooledObjectFactory.activeObject進(jìn)行激活,然后使用PooledObjectFactory.validateObject方法進(jìn)行驗(yàn)證后再返回
returnObject將一個(gè)對(duì)象返還給池。根據(jù)約定:對(duì)象必須 是使用borrowObject方法從池中借出的
invalidateObject廢棄一個(gè)對(duì)象。根據(jù)約定:對(duì)象必須 是使用borrowObject方法從池中借出的。通常在對(duì)象發(fā)生了異?;蚱渌麊?wèn)題時(shí)使用此方法廢棄它
addObject使用工廠創(chuàng)建一個(gè)對(duì)象,鈍化并且將它放入空閑對(duì)象池
getNumberIdle返回池中空閑的對(duì)象數(shù)量。有可能是池中可供借出對(duì)象的近似值。如果這個(gè)信息無(wú)效,返回一個(gè)負(fù)數(shù)
getNumActive返回從借出的對(duì)象數(shù)量。如果這個(gè)信息不可用,返回一個(gè)負(fù)數(shù)
clear清除池中的所有空閑對(duì)象,釋放其關(guān)聯(lián)的資源(可選)。清除空閑對(duì)象必須使用PooledObjectFactory.destroyObject方法
close關(guān)閉池并釋放關(guān)聯(lián)的資源

到此這篇關(guān)于詳解Java中對(duì)象池的介紹與使用的文章就介紹到這了,更多相關(guān)Java對(duì)象池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot整合Shiro實(shí)現(xiàn)單點(diǎn)登錄的示例代碼

    spring boot整合Shiro實(shí)現(xiàn)單點(diǎn)登錄的示例代碼

    本篇文章主要介紹了spring boot整合Shiro實(shí)現(xiàn)單點(diǎn)登錄的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • java jni調(diào)用c函數(shù)實(shí)例分享(java調(diào)用c函數(shù))

    java jni調(diào)用c函數(shù)實(shí)例分享(java調(diào)用c函數(shù))

    Java代碼中調(diào)用C/C++代碼,當(dāng)然是使用JNI,JNI是Java native interface的簡(jiǎn)寫,可以譯作Java原生接口,下面看實(shí)例吧
    2013-12-12
  • maven打生產(chǎn)環(huán)境可執(zhí)行包的實(shí)現(xiàn)

    maven打生產(chǎn)環(huán)境可執(zhí)行包的實(shí)現(xiàn)

    本文主要介紹了maven打生產(chǎn)環(huán)境可執(zhí)行包的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • java中staticclass靜態(tài)類詳解

    java中staticclass靜態(tài)類詳解

    這篇文章主要介紹了java中staticclass靜態(tài)類詳解,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • 解決Idea的選擇文件后定位瞄準(zhǔn)器"Select Opened File"的功能不見了

    解決Idea的選擇文件后定位瞄準(zhǔn)器"Select Opened File"的功能

    使用IntelliJ IDEA時(shí),可能會(huì)發(fā)現(xiàn)"SelectOpenedFile"功能不見了,這個(gè)功能允許用戶快速定位到當(dāng)前打開文件的位置,若要找回此功能,只需在IDEA的標(biāo)題欄上右鍵,然后選擇"Always Select Opened File",這樣就可以重新啟用這個(gè)便捷的功能
    2024-11-11
  • 使用javafx更新UI的方法

    使用javafx更新UI的方法

    這篇文章主要介紹了使用javafx更新UI的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 1小時(shí)快速上手RabbitMQ(簡(jiǎn)介及安裝過(guò)程)

    1小時(shí)快速上手RabbitMQ(簡(jiǎn)介及安裝過(guò)程)

    RabbitMQ簡(jiǎn)稱MQ全稱是Message Queue(消息隊(duì)列),是在消息的傳輸過(guò)程中保存消息的容器,多用于分布式系統(tǒng)之間進(jìn)行通信,本文給大家講解了RabbitMQ簡(jiǎn)介與安裝,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友跟隨小編一起看看吧
    2023-01-01
  • Eclipse項(xiàng)目有紅感嘆號(hào)的解決方法

    Eclipse項(xiàng)目有紅感嘆號(hào)的解決方法

    這篇文章主要為大家詳細(xì)介紹了Eclipse項(xiàng)目有紅感嘆號(hào)的解決方法,給出了Eclipse項(xiàng)目有紅感嘆號(hào)的原因,以及如何解決?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java虛擬機(jī)最多支持多少個(gè)線程的探討

    Java虛擬機(jī)最多支持多少個(gè)線程的探討

    這篇文章主要介紹了Java虛擬機(jī)最多支持多少個(gè)線程的問(wèn)題,從StackOverflow上摘錄而來(lái),需要的朋友可以參考下
    2014-04-04
  • Mybatis批量插入返回成功的數(shù)目實(shí)例

    Mybatis批量插入返回成功的數(shù)目實(shí)例

    這篇文章主要介紹了Mybatis批量插入返回成功的數(shù)目實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12

最新評(píng)論