<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    https://my.oschina.net/xinxingegeya/blog/391560

    commons.pool2 對象池的使用

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


    池對象工廠 PooledObjectFactory和池對象 DefaultPooledObject

    先了解個概念:

    池對象工廠(PooledObjectFactory接口):用來創建池對象, 將不用的池對象進行鈍化(passivateObject), 對要使用的池對象進行激活(activeObject), 對池對象進行驗證(validateObject), 對有問題的池對象進行銷毀(destroyObject)等工作

    PooledObjectFactory是一個池化對象工廠接口,定義了生成對象、激活對象、鈍化對象、銷毀對象的方法,如下

    public interface PooledObjectFactory<T{     PooledObject<T> makeObject() throws Exception;      void destroyObject(PooledObject<T> var1) throws Exception;      boolean validateObject(PooledObject<T> var1);      void activateObject(PooledObject<T> var1) throws Exception;      void passivateObject(PooledObject<T> var1) throws Exception; }

    如果需要使用Commons-Pool,那么你就需要提供一個PooledObjectFactory接口的具體實現。一個比較簡單的辦法就是,繼承BasePooledObjectFactory這個抽象類。而繼承這個抽象類,只需要實現兩個方法:create()和wrap(T obj)。

    實現create()方法很簡單,而實現wrap(T obj)也有捷徑,可以使用類DefaultPooledObject,代碼可以參考如下:

    import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.impl.DefaultPooledObject;  /**  * Created by liyanxin on 2015/3/25.  */ public class PooledStringBufferFactory extends BasePooledObjectFactory<StringBuffer{      @Override     public StringBuffer create() throws Exception {         return new StringBuffer(16);     }      @Override     public PooledObject<StringBuffer> wrap(StringBuffer stringBuffer) {         return new DefaultPooledObject<StringBuffer>(stringBuffer);     } }

    當然還有其他的池對象工廠,如KeyedPooledObjectFactory,和PooledObjectFactory接口類似,只是在相關的方法中多了Key參數,如下,

    public interface KeyedPooledObjectFactory<K,V{         PooledObject<V> makeObject(K key) throws Exception;        void destroyObject(K key, PooledObject<V> p) throws Exception;      boolean validateObject(K key, PooledObject<V> p);         void activateObject(K key, PooledObject<V> p) throws Exception;      void passivateObject(K key, PooledObject<V> p) throws Exception; }


    創建對象池 GenericObjectPool

    在org.apache.commons.pool2.impl中預設了三個可以直接使用的對象池:GenericObjectPool、GenericKeyedObjectPool和SoftReferenceObjectPool。

    通常使用GenericObjectPool來創建對象池,如果是對象池是Keyed的,那么可以使用GenericKeyedObjectPool來創建對象池。這兩個類都提供了豐富的配置選項。這兩個對象池的特點是可以設置對象池中的對象特征,包括LIFO(后進先出)方式、最大空閑數、最小空閑數、是否有效性檢查等等。兩者的區別如前面所述,后者支持Keyed。

    而SoftReferenceObjectPool對象池,它利用一個java.util.ArrayList對象來保存對象池里的對象。不過它并不在對象池里直接保存對象本身,而是保存它們的“軟引用”

    (Soft Reference)。這種對象池的特色是:可以保存任意多個對象,不會有容量已滿的情況發生;在對象池已空的時候,調用它的borrowObject方法,會自動返回新創建的實例;可以在初始化同時,在池內預先創建一定量的對象;當內存不足的時候,池中的對象可以被Java虛擬機回收。

    舉個例子:

    new GenericObjectPool<StringBuffer>(new PooledStringBufferFactory());

    我們也可以使用GenericObjectPoolConfig來對上面創建的對象池進行一些參數配置,創建的Config參數,可以使用setConfig方法傳給對象池,也可以在對象池的構造方法中作為參數傳入。

    舉個例子:

    GenericObjectPoolConfig conf = new GenericObjectPoolConfig(); conf.setMaxTotal(20); conf.setMaxIdle(10); ... GenericObjectPool<StringBuffer> pool = new GenericObjectPool<StringBuffer>(new PooledStringBufferFactory(), conf);


    使用對象池

    對象池使用起來很方便,簡單一點就是使用borrowObject和returnObject兩個方法,直接給參考代碼吧:

    borrowObject部分代碼,具體請看源碼:借出池對象,通過新建create()或從idleObjects雙端隊列中返回池對象。idleObjects是一個雙端隊列,保存返回對象池的對象,下次用的時候按照LIFO的原則(或其他原則)借出對象。

    public T borrowObject(long borrowMaxWaitMillis) throws Exception {     PooledObject<T> p = null;      while (p == null) {         create = false;         if (blockWhenExhausted) {             p = idleObjects.pollFirst();             if (p == null) {                 p = create();                 if (p != null) {                     create = true;                 }             }             if (p == null) {                 if (borrowMaxWaitMillis < 0) {                     p = idleObjects.takeFirst();                 } else {                     p = idleObjects.pollFirst(borrowMaxWaitMillis,                             TimeUnit.MILLISECONDS);                 }             }             if (p == null) {                 throw new NoSuchElementException(                         "Timeout waiting for idle object");             }             if (!p.allocate()) {                 p = null;             }         } else {             p = idleObjects.pollFirst();             if (p == null) {                 p = create();                 if (p != null) {                     create = true;                 }             }         }     }     return p.getObject(); }

    returnObject方法,部分代碼,具體請看源碼:返回池對象,放入idleObjects雙端隊列保存。

    關鍵代碼:

    public void returnObject(T obj{     PooledObject<T> p = allObjects.get(obj);      int maxIdleSave = getMaxIdle();     if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {         try {             destroy(p);         } catch (Exception e) {             swallowException(e);         }     } else {         if (getLifo()) {             idleObjects.addFirst(p);         } else {             idleObjects.addLast(p);         }     }     updateStatsReturn(activeTime); }

    這只是大體上的邏輯,還有更多的細節邏輯控制。比如什么時候銷毀,什么時候創建等等。

    posted on 2016-12-20 15:36 jinfeng_wang 閱讀(533) 評論(0)  編輯  收藏 所屬分類: 2016-thinking
    主站蜘蛛池模板: 亚洲AV无码成人网站在线观看| 国产精品福利在线观看免费不卡| 又粗又大又长又爽免费视频| 一级毛片人与动免费观看| 亚洲精品成人网站在线观看| 国产日本一线在线观看免费| 美女被吸屁股免费网站| 亚洲国产精品免费视频| 午夜免费福利网站| 四虎影视在线影院在线观看免费视频 | 亚洲成av人片在线天堂无| 国产亚洲av片在线观看18女人| 永久在线免费观看| 黄色免费网址大全| 亚洲欧洲高清有无| 亚洲国产精品专区在线观看 | 精品无码人妻一区二区免费蜜桃 | 亚洲欧洲另类春色校园网站| 亚洲裸男gv网站| 少妇高潮太爽了在线观看免费| 久久WWW免费人成—看片| 亚洲 欧洲 自拍 另类 校园| 亚洲一区爱区精品无码| 好爽好紧好大的免费视频国产| 久久久久国产精品免费网站| 国产91成人精品亚洲精品| 亚洲人成网站18禁止久久影院| 中文字幕亚洲日本岛国片| 在线观看免费人成视频色9| 国产成人免费AV在线播放| 亚洲成av人在线观看网站| 亚洲人成高清在线播放| 国产亚洲AV无码AV男人的天堂| 国产成人免费永久播放视频平台| 3d动漫精品啪啪一区二区免费| 一区二区在线免费视频| 亚洲AV无码专区在线观看成人| 亚洲国产精品线观看不卡| 亚洲AV无码久久精品成人| 亚洲国产人成精品| 四虎永久成人免费影院域名|