1. 程式人生 > >java 通用物件池的實現

java 通用物件池的實現

本文以apache common-pools為例

主要組成類

PooledObject(可被池化的物件)

預設實現DefaultPooledObject,裡面封裝了一個真正的使用者需要池化的物件object。
這裡寫圖片描述

其中DefaultPooledObject裡面有兩個方法:

Exception borrowedBy :用於記錄上次呼叫borrow時的堆疊,用於跟蹤程式碼呼叫情況

 @Override
    public synchronized boolean allocate() {
        if (state == PooledObjectState.IDLE) {
            state = PooledObjectState.ALLOCATED;
            lastBorrowTime = System.currentTimeMillis();
            lastUseTime = lastBorrowTime;
            borrowedCount++;
            if
(logAbandoned) { borrowedBy = new AbandonedObjectCreatedException(); } return true; } else if (state == PooledObjectState.EVICTION) { // TODO Allocate anyway and ignore eviction test state = PooledObjectState.EVICTION_RETURN_TO_HEAD; return
false; } // TODO if validating and testOnBorrow == true then pre-allocate for // performance return false; }

Exception usedBy: 同上,記錄use時的堆疊


  @Override
    public void use() {
        lastUseTime = System.currentTimeMillis();
        usedBy = new Exception("The last code to use this object was:"
); }

PooledObjectState

物件的狀態,也即生命週期
這裡寫圖片描述

  • allocated :此物件被客戶端使用中
  • idle :在池中,處於空閒狀態
  • eviction:在例項化GenericObjectPool物件時,內部會啟動一個EvictionTimer執行緒執行緒,定期(timeBetweenEvictionRunsMillis)執行evict方法,以EvictionPolicy策略destory 狀態處於idle過長的物件或idle數太多的時候。
  • abandoned:當池中的物件被客戶端拿出後,若長時間(removeAbandonedTimeout)未返回池中,或沒有呼叫use方法,即被標記為拋棄的,當執行removeAbandoned方法時從池中destory,並若logAbandoned為true的話,則列印呼叫堆疊

PooledObjectFactory(物件建立工廠)

這裡寫圖片描述

一般需要程式設計師繼承BasePooledObjectFactory,建立需要池化的物件:

 private static class ShardedJedisFactory implements PooledObjectFactory<ShardedJedis> {
    private List<JedisShardInfo> shards;
    private Hashing algo;
    private Pattern keyTagPattern;

    public ShardedJedisFactory(List<JedisShardInfo> shards, Hashing algo, Pattern keyTagPattern) {
      this.shards = shards;
      this.algo = algo;
      this.keyTagPattern = keyTagPattern;
    }

    @Override
    public PooledObject<ShardedJedis> makeObject() throws Exception {
      ShardedJedis jedis = new ShardedJedis(shards, algo, keyTagPattern);
      return new DefaultPooledObject<ShardedJedis>(jedis);
    }

    @Override
    public void destroyObject(PooledObject<ShardedJedis> pooledShardedJedis) throws Exception {
      final ShardedJedis shardedJedis = pooledShardedJedis.getObject();
      for (Jedis jedis : shardedJedis.getAllShards()) {
        if (jedis.isConnected()) {
          try {
            try {
              jedis.quit();
            } catch (Exception e) {

            }
            jedis.disconnect();
          } catch (Exception e) {

          }
        }
      }
    }

    @Override
    public boolean validateObject(PooledObject<ShardedJedis> pooledShardedJedis) {
      try {
        ShardedJedis jedis = pooledShardedJedis.getObject();
        for (Jedis shard : jedis.getAllShards()) {
          if (!shard.ping().equals("PONG")) {
            return false;
          }
        }
        return true;
      } catch (Exception ex) {
        return false;
      }
    }

    @Override
    public void activateObject(PooledObject<ShardedJedis> p) throws Exception {

    }

    @Override
    public void passivateObject(PooledObject<ShardedJedis> p) throws Exception {

    }
  }

GenericObjectPoolConfig(物件池配置)

這裡寫圖片描述

  • lifo:後進先出,或者先進先出
  • maxWaitMillis:從idle佇列裡面取物件時,若阻塞的話,則最大等待時長
  • minEvictableIdleTimeMillis:處於idle狀態超過此值時,會被destory
  • softMinEvictableIdleTimeMillis:處於idle狀態超過此值,且處於idle狀態個數大於minIdle時會被destory ,正常情況下softMinEvictableIdleTimeMillis < minEvictableIdleTimeMillis
  • numTestsPerEvictionRun: evict執行緒每次遍歷時evict的個數
  • testOnCreate:當create物件時,是否測試池化的物件是否存活
  • testOnBorrow: 同上,從池中borrow出來時測試
  • testOnReturn:同上,歸還池中時測試
  • testWhileIdle:同上,idle狀態時測試
  • timeBetweenEvictionRunsMillis:evict執行緒每次間隔時間
  • blockWhenExhausted:從池中取物件時,若池子用盡的話,是否阻塞等待一會maxWaitMillis
  • jmxEnabled:jmx是否開啟監控

AbandonedConfig(防止物件洩露)

這裡寫圖片描述

  • abandoned:被拋棄的,即被池拋棄的設定(客戶端從池裡面取出去後,若長時間不歸還池中,則拋棄並destory)並通過配置可以設定是否logAbandoned,若true的話,則把拋棄物件時,列印相關的日誌(呼叫日誌)

主要流程

evict執行緒流程

這裡寫圖片描述

相關推薦

java 通用物件實現

本文以apache common-pools為例 主要組成類 PooledObject(可被池化的物件) 預設實現DefaultPooledObject,裡面封裝了一個真正的使用者需要池化的物件object。 其中DefaultPoole

Java線程實現原理與技術

到來 res ble 的區別 數據庫連接 sca 講解 屬性 活動 本文將通過實現一個簡易的線程池理解線程池的原理,以及介紹JDK中自帶的線程池ThreadPoolExecutor和Executor框架。 1.無限制線程的缺陷 多線程的軟件設計方法確實可以最大限度地發揮

Java執行緒實現原理與技術I

無限制執行緒的缺陷 多執行緒的軟體設計方法確實可以最大限度地發揮多核處理器的計算能力,提高生產系統的吞吐量和效能。但是,若不加控制和管理的隨意使用執行緒,對系統的效能反而會產生不利的影響。 一種最為簡單的執行緒建立和回收的方法類似如下: new Thread(new 

CocosCreator之KUOKUO帶你利用物件實現cc.graphics的單步撤銷

本次引擎2.0.5 編輯工具VSCode   目標:畫筆單步撤銷。 方法:物件池儲存節點,通過回收實現單步撤銷。   新建工程:bk白色背景。 新建個空節點:drawManager(便於管理預製體) 然後新建一個空節點,綁上cc.graphi

Java執行緒實現原理與技術II

為了能夠更好地控制多執行緒,JDK提供了一套Executor框架,幫助開發人員有效地進行執行緒控制。Executor框架無論是newFixedThreadPool()方法、newSingleThreadExecutor()方法還是ewCachedThreadPool()方法,其內部實現均使用了

通用物件

最近做一款音樂遊戲,需要顯示較多的音符,需頻繁回收利用GameObject,簡易的物件池滿足不了需求,以前寫過幾個物件池, 使用起來有比較有侷限性,不是很方便,就考慮寫一個通用的物件池,可以適用於各種專案型別,而且呼叫要簡便。參考了一些資料,並利用This添加了靜態方法,方便

commons-pool物件實現原理及使用(一)

我們知道頻繁的建立物件是一個相對較重的過程,jvm要載入類,初始化物件,為物件分配記憶體涉及到多個系統呼叫,這樣對一個高負載的系統來說是比較消耗資源的。這時我們可以將所需物件進行池化,apache開源的的commons-pool是一個比較經典的實現物件池化元件,筆者所在的公

commons-pool2原始碼走讀(四) 物件實現GenericObjectPool

commons-pool2原始碼走讀(四) 物件池實現GenericObjectPool<T> GenericObjectPool <T> 是一個可配置的ObjectPool實現。 當與適當的PooledObjectFactory組合使用時,GenericO

Delphi 高效的通用物件

       物件池的設計,可以讓一定頻繁使用到的物件可以重用, 無需不斷進行create/destroy,極大加快了執行效率.   下面是一個非常簡單的利用佇列設計而成執行緒安全的通用物件池. unit uObjPoolUnit; interface { 通用的

簡析java執行緒 實現原理

什麼是執行緒池     執行緒池是一種多執行緒處理的形式,通過把處理的任務新增到佇列中,然後在建立執行緒後自動執行這些任務。執行緒池可以同時執行多個任務,如果任務佇列已經滿了,則新來的任務就會排隊等待,執行緒池執行緒的數量永遠不會大於既定最大值。 Exector

[Unity3D]通用物件類ResourcePool

通用物件池,使用時會將常用的物件至於池頂,如果設定了池的大小,超出池的未經常使用的物件將被移除,並且執行回撥,可在回撥中對移除物件進行其他操作。 可對壓入的物件進行命名,通過名字來進行查詢和刪除。 原始碼 using System.Collections;

併發程式設計(十一)—— Java 執行緒 實現原理與原始碼深度解析(一)

史上最清晰的執行緒池原始碼分析 鼎鼎大名的執行緒池。不需要多說!!!!! 這篇部落格深入分析 Java 中執行緒池的實現。 總覽 下圖是 java 執行緒池幾個相關類的繼承結構:    先簡單說說這個繼承結構,Executor 位於最頂層,也是最簡單的,就一個 execute(

併發程式設計(十二)—— Java 執行緒 實現原理與原始碼深度解析 之submit方法 (二)

在上一篇《併發程式設計(十一)—— Java 執行緒池 實現原理與原始碼深度解析(一)》中提到了執行緒池ThreadPoolExecutor的原理以及它的execute方法。這篇文章是接著上一篇文章寫的,如果你沒有閱讀上一篇文章,建議你去讀讀。本文解析ThreadPoolExecutor#submit。  

Java執行緒實現原理

引數配置 核心池大小、最大池大小 /** * Core pool size is the minimum number of workers to keep alive * (and not allow to time out et

Java執行緒實現原理詳解

原理概述 其實java執行緒池的實現原理很簡單,說白了就是一個執行緒集合workerSet和一個阻塞佇列workQueue。當用戶向執行緒池提交一個任務(也就是執行緒)時,執行緒池會先將任務放入workQueue中。workerSet中的執行緒會不斷的從w

java資料庫連線實現原理

原文:http://blog.csdn.net/frightingforambition/article/details/25464129  一、為什麼在連線資料庫時要使用連線池  資料庫連線是一種關鍵的有限的昂貴的資源,這一點在多使用者的網頁應用程式中體現得

Java執行緒實現原理與原始碼解析(jdk1.8)

為什麼需要執行緒池? 執行緒池能夠對執行緒進行統一分配,調優和監控: - 降低資源消耗(執行緒無限制地建立,然後使用完畢後銷燬) - 提高響應速度(無須建立執行緒) - 提高執行緒的可管理性 Java是如何實現和管理執行緒池的? 從JDK 5開始,把

Java執行緒實現

電腦的CPU資源是有限的,任務的處理速度與執行緒數量之間並不是正相關。當執行緒數量過多,CPU要頻繁的在不同執行緒切換,反而會引起處理效能的下降。執行緒池中最大的執行緒數,是考慮多種因素來事先設定的,比如硬體的條件,業務的型別等等。 當我們向一個固定大小的的執行緒池中請求一個執行緒時,當執行緒池中沒有空閒資源

一個通用併發物件實現

原文連結,譯文連結,原文作者: Sarma Swaranga,本文最早發表於deepinmind,校對:鄭旭東 這篇文章裡我們主要討論下如何在Java裡實現一個物件池。最近幾年,Java虛擬機器的效能在各方面都得到了極大的提升,因此對大多數物件而言,已經沒有必要通過物件池來提高效能了。根本的原

Java 線程的原理與實現

控制 try 所在 使用 urn str waiting media .info 這幾天主要是狂看源程序,在彌補了一些曾經知識空白的同一時候,也學會了不少新的知識(比方 NIO)。或者稱為新技術吧。 線程池就是當中之中的一個,一提到線程。我們會想到曾經《操作系統》的