common-pool2 使用

common-pool2 使用

common-pool2提供了3中對象池管理方式,它們的使用方式基本同樣,這裏以GenericObjectPool對象池爲例介紹其使用方式,通常實現本身的對象池須要通過2個步驟java

  1. 實現PooledObjectFactory接口:該接口是一種工廠模式,實現其目的是讓對象池經過該工廠模式建立管理的對象apache

  2. 建立對象池(GenericObjectPool(PooledObjectFactory))實例app

建立Conn對象池

咱們假設Conn對象是一個創建TCP鏈接的對象,該對象的初始化時間平均爲500ms,爲了不在程序中頻繁建立Conn對象,咱們須要藉助對象池管理Conn對象實例ide

import org.slf4j.LoggerFactory;

/**
 * common-pool2 使用方式
 * <p/>
 * 假設這是一個創建TCP鏈接的對象,該對象的初始化時間平均爲500ms,爲了不在程序中頻繁建立Conn對象,咱們須要藉助對象池管理Conn對象實例
 *
 * @author WangJun <wangjuntytl@163.com>
 * @version 1.0 15/10/28
 * @since 1.6
 */

public class Conn {

    /**
     * 記錄對象的建立時間
     */
    private long createTime;


    /**
     * 初始化Conn對象,模擬建立Conn對象平均消耗500ms
     * @throws InterruptedException
     */
    public Conn() throws InterruptedException {
        Thread.sleep(500);
        createTime = System.currentTimeMillis();
        LoggerFactory.getLogger(getClass()).debug(" init conn suc... " + createTime);
    }

    /**
     * 報告Conn對象信息
     */
    public void report() {
        LoggerFactory.getLogger(getClass()).info("this is a available conn " + createTime);
    }
}

利用工廠模式,使對象池經過該工廠模式建立管理的對象

package com.peaceful.pool.demo;
    
    import org.apache.commons.pool2.BasePooledObjectFactory;
    import org.apache.commons.pool2.PooledObject;
    import org.apache.commons.pool2.PooledObjectFactory;
    import org.apache.commons.pool2.impl.DefaultPooledObject;
    
    /**
     * common-pool2 使用方式
     * <p/>
     * 爲了使用common-pool2對象池管理,咱們必須實現{@link org.apache.commons.pool2.PooledObjectFactory}或者其子類
     * 這是一個工廠模式,告訴對象池怎樣去建立要管理的對象
     * <p/>
     * BasePooledObjectFactory 是對{@link org.apache.commons.pool2.PooledObjectFactory}的一個基本實現,咱們能夠繼承該類,減小一些方法的實現
     * <p/>
     * 在實現{@link org.apache.commons.pool2.PooledObjectFactory}接口時,咱們必定要實現的接口方法是{@link PooledObjectFactory#makeObject()}方法。
     *
     * @author WangJun <wangjuntytl@163.com>
     * @version 1.0 15/10/28
     * @since 1.6
     */
    
    public class ConnFactory extends BasePooledObjectFactory<Conn> {
    
    
        /**
         * 間接實現{@link PooledObjectFactory#makeObject()}方法,代表怎樣建立須要管理對象
         */
        @Override
        public Conn create() throws Exception {
            return new Conn();
        }
    
    
        /**
         * 在common-pool2中爲了統計管理的對象的一些信息,好比調用次數,空閒時間,上次使用時間等,須要對管理的對象進行包裝,而後在放入到對象池中
         *
         * @param obj 對象池要管理的對象
         * @return 返回包裝後的PooledObject對象
         */
        @Override
        public PooledObject<Conn> wrap(Conn obj) {
            return new DefaultPooledObject<Conn>(obj);
        }
    
    }

爲了模擬的更真實,ConnPool池可讓使用者個性化配置

package com.peaceful.pool.demo;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    /**
     * common-pool2 使用方式
     * <p/>
     * {@link org.apache.commons.pool2.impl.GenericObjectPool}支持個性化配置,咱們能夠配置對象池中總共的對象數,最大、最小空閒對象數等等
     * 這邊繼承{@link GenericObjectPoolConfig}是爲了ConnPool也能夠進行個性化的配置
     *
     * @author WangJun <wangjuntytl@163.com>
     * @version 1.0 15/10/28
     * @since 1.6
     */
    
    public class ConnPoolConfig extends GenericObjectPoolConfig {
    
        public ConnPoolConfig() {
            // defaults to make your life with connection pool easier :)
            setMinIdle(5);
            setTestOnBorrow(true);
        }
    
    }

有了建立對象的工廠,咱們就能夠建立一個對象池實例

package com.peaceful.pool.demo;
    
    import org.apache.commons.pool2.impl.GenericObjectPool;
    
    /**
     * common-pool2 使用方式
     * <p/>
     * Conn對象管理池,這裏利用GenericObjectPool做爲對象池
     *
     * @author WangJun <wangjuntytl@163.com>
     * @version 1.0 15/10/28
     * @since 1.6
     */
    
    public class ConnPool extends GenericObjectPool<Conn> {
    
    
        /**
         * 調用{@link GenericObjectPool}的構造方法,構造ConnPool
         */
        public ConnPool() {
            super(new ConnFactory(), new ConnPoolConfig());
        }
    
        /**
         * 調用{@link GenericObjectPool}的構造方法,構造ConnPool
         */
        public ConnPool(ConnPoolConfig connPoolConfig) {
            super(new ConnFactory(), connPoolConfig);
        }
    
    }

這樣一個就完成了整個ConnPool的編碼,下面咱們在寫一個demo,演示使用ConnPool

public class ConnDemo {
    
        public static void main(String[] args) throws Exception {
            ConnPoolConfig connPoolConfig = new ConnPoolConfig();
            connPoolConfig.setMinIdle(5);
            connPoolConfig.setMaxIdle(8);
            ConnPool connPool = new ConnPool(connPoolConfig);
            Conn conn1 = connPool.borrowObject();
            Conn conn2 = connPool.borrowObject();
            Conn conn3 = connPool.borrowObject();
            Conn conn4 = connPool.borrowObject();
            Conn conn5 = connPool.borrowObject();
            conn1.report();
            connPool.returnObject(conn1);
            conn2.report();
            connPool.returnObject(conn2);
            conn3.report();
            connPool.returnObject(conn3);
            conn4.report();
            connPool.returnObject(conn4);
            conn5.report();
            connPool.returnObject(conn5);
    
            conn5.report();
    
            // 被歸還的對象的引用,不能夠在次歸還
            // java.lang.IllegalStateException: Object has already been retured to this pool or is invalid
            try {
                connPool.returnObject(conn5);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

下面是ConnDemo的運行結果this

[2015-10-28 14:56:06 DEBUG]  {com.peaceful.pool.demo.Conn:18}- init conn suc...
[2015-10-28 14:56:07 DEBUG]  {com.peaceful.pool.demo.Conn:18}- init conn suc...
[2015-10-28 14:56:07 DEBUG]  {com.peaceful.pool.demo.Conn:18}- init conn suc...
[2015-10-28 14:56:08 DEBUG]  {com.peaceful.pool.demo.Conn:18}- init conn suc...
[2015-10-28 14:56:08 DEBUG]  {com.peaceful.pool.demo.Conn:18}- init conn suc...
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015366746
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015367346
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015367853
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368354
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368860
[2015-10-28 14:56:08 INFO ]  {com.peaceful.pool.demo.Conn:22}-this is a available conn 1446015368860
java.lang.IllegalStateException: Object has already been retured to this pool or is invalid
    at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:595)
    at com.peaceful.pool.demo.ConnDemo.main(ConnDemo.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
相關文章
相關標籤/搜索